这是我的代码。
def getch():
fd = sys.stdin.fileno()
old_Settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
sys.stdin.flush()
except KeyboardInterrupt:
print ("[Error] Abnormal program termination")
finally:
termios.tcsetattr(fd,termios.TCSADRAIN,old_settings)
return ch
Run Code Online (Sandbox Code Playgroud)
在此代码中,KeyboardInterrupt异常不起作用。
谢谢
是的,当您将TTY设置为原始模式时,或者特别是在禁用termios设置时,您将ISIG不再获得相应的行为:
Run Code Online (Sandbox Code Playgroud)ISIG When any of the characters INTR, QUIT, SUSP, or DSUSP are received, generate the corresponding signal.
换句话说,在大多数终端中,该字符INTR又^C不再产生SIGINT信号,这是Python用于引发的信号KeyboardInterrupt。
这样,全屏程序emacs就可以^C用作控制角色而不仅仅是退出。
因此,有两种选择:
而不是调用setraw,而是设置所需的确切termios标志集,并确保不要禁用ISIG。
值得一看的是Python的源代码,tty.setraw以确切地了解它的作用,并将其用作基准。
如果没有,您可以做完全相同的事情ISIG。但实际上,您应该阅读文档以了解这些内容的含义。
并确保man termios在您自己的系统上不要在线搜索;Linux与macOS / * BSD的情况有些不同,即使同一OS的版本之间也存在细微的差异。
即使在阅读了文档并进行了自己的实验之后,也可能并不完全清楚每种设置都有什么作用。本文似乎做了不错的工作,解释了进入原始模式的内容以及每个相关标志的实际含义(尽管我只是快速浏览了一下,而且,您仍然需要阅读man termios适用于平台的内容)。
另外,您也可以^C手动处理。
您已经可以使用来同时读取一个字符sys.stdin.read(1),因此当有人按下时^C,您将要读取一个'\x03'字符。
发生这种情况时,您可以做任何您想做的事情,包括raise KeyboardInterrupt。
附带说明一下,如果是Python 3,则可能要以二进制模式阅读:
ch = sys.stdin.buffer.raw.read(1)
sys.stdin.flush()
Run Code Online (Sandbox Code Playgroud)
(然后,您将检查b'\x03'而不是'\x03'。)
在文本模式下,即使它是UTF-8中的多字节字符(或任何语言环境),也应一次获得一个完整字符。乍一看似乎比较简单,但实际上可能会产生误导,因为单个字符仍然只能是按键的一部分。例如,在大多数终端上,向上箭头发送3个字符('\x1B[A'), butread(1)`只会为您提供第一个字符。
| 归档时间: |
|
| 查看次数: |
397 次 |
| 最近记录: |