退出input() / raw_input()后终端状态异常(文本不可见/无回显)

23 投票
4 回答
8675 浏览
提问于 2025-04-17 05:14

我正在用Python 3写一个小工具应用程序(下面的测试案例在Python 2中也能运行),并使用PyQt 4来创建一个可以和Qt窗口互动的REPL提示符。

不过,我遇到了一个解决不了的问题:当我在应用程序中使用exit()退出时,如果code模块正在执行input()(在Python 2.x中叫raw_input()),我的Linux终端就不再显示我输入的字符了。也就是说,终端似乎处于一种坏掉的状态,可能是因为input()发出了一些转义序列。

我尝试了很多方法来解决这个问题,包括使用curses模块和其他方法在运行exit之前重置终端,甚至尝试模拟stdin流来通过实际将exit()传递给input()来退出(不幸的是,code.InteractiveConsole.push()并不是像人们想的那样工作),还尝试用threading写一个自己的非阻塞input(),但都没有成功。

在这里,有一些关于类似问题的讨论:这里这里这里这里

最后,这里有一个简化的测试案例来演示这个问题:

#!/usr/bin/env python3

import code
import sys
from PyQt4.QtGui import QApplication, QWidget

app = QApplication(sys.argv)

app.lastWindowClosed.connect(exit)

widget = QWidget()
widget.show()

code.interact()

对于不熟悉(Py)Qt的人来说,这个程序会打开一个空白窗口,当窗口关闭时,applastWindowClosed信号会触发内置的exit()函数。这发生在code模块正在执行input()来从sys.stdin读取输入的时候。而在这里,当我关闭窗口后,终端中输入的字符都不显示了。

我主要使用Python 3,实际的应用程序使用的是Python 3特有的代码,但我也在Python 2.7中尝试了这个测试案例,结果显示同样的问题。

4 个回答

3

来自 Quentin Engles 的回答对我也有帮助,但作为一个刚接触Python的新手,我不太明白 stty sane 应该放在哪里。在经过一番寻找和思考后,我明白了 exit 是指 exit() 这个方法,所以我创建了一个叫 exiting() 的方法,并传递了一个引用给它:

#!/usr/bin/env python3

import code
import sys
from PyQt4.QtGui import QApplication, QWidget

def exiting():
    os.system('stty sane')
    exit()

app = QApplication(sys.argv)

app.lastWindowClosed.connect(exiting)

widget = QWidget()
widget.show()

code.interact()
21

这并不是解决问题的真正办法,但如果你在关闭应用程序后,在终端里输入“reset”,它就会恢复正常。

我之前在开发一个C语言应用时也遇到过类似的问题,因为它没有正确关闭一个管道。也许这里发生的情况也有点像。

33

试试这个命令 os.system('stty sane')。这个 stty sane 命令是用来重置一些设置的,比如让屏幕上的输出恢复正常,听说还有其他一些作用。

撰写回答