gpt4 book ai didi

python tty.setraw Ctrl + C 不起作用(getch)

转载 作者:太空狗 更新时间:2023-10-30 02:37:04 26 4
gpt4 key购买 nike

这是我的代码。

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

在此代码中,KeyboardInterrupt 异常不起作用。

谢谢

最佳答案

是的,当您将 TTY 设置为原始模式时——或者,特别是当您禁用 termios 时设置 ISIG——你不再得到相应的行为:

  ISIG   When any of the characters INTR, QUIT, SUSP, or DSUSP are
received, generate the corresponding signal.

换句话说,字符 INTR,在大多数终端中也称为 ^C,不再生成 SIGINT 信号,is what Python uses to raise a KeyboardInterrupt .

这就是像 emacs 这样的全屏程序可以使用 ^C 作为控制字符而不只是退出的方式。

所以,有两种选择:


不要调用 setraw,而是设置您想要的一组确切的 termios 标志,确保不要禁用 ISIG

值得查看 Python 的 tty.setraw 的源代码看看它到底做了什么,用作基线。

如果没有 ISIG,您也可以做同样的事情。但实际上,您应该阅读文档以了解其中每一项的含义。

并确保在你自己的系统上man termios,不要上网搜索;在 Linux 和 macOS/*BSD 上有些不同,即使是同一操作系统的不同版本之间也存在细微差别。

即使阅读了文档并自己进行了试验,也可能并不完全清楚每个设置的效果。 This article似乎在解释进入原始模式的内容以及每个相关标志的实际含义方面做得不错(尽管我只是快速浏览了一下 - 而且。再次重申,您仍然需要阅读 man termios 以获得你的平台)。


或者,您可以手动处理 ^C

您已经使用 sys.stdin.read(1) 一次读取一个字符,因此当有人点击 ^C 时,您将读取'\x03' 字符。

当发生这种情况时,您可以做任何您想做的事情,包括raise KeyboardInterrupt


作为旁注,如果这是 Python 3,您可能希望以二进制模式阅读:

ch = sys.stdin.buffer.raw.read(1)
sys.stdin.flush()

(然后您将检查 b'\x03' 而不是 '\x03'。当然。)

在文本模式下,您应该一次获得一个完整的字符,即使它是 UTF-8(或您的语言环境是什么)中的多字节字符。乍一看,这似乎更简单——但这实际上可能会产生误导,因为单个字符仍然可能只是击键的一部分。例如,对于大多数终端,向上箭头发送 3 个字符 ('\x1B[A'),但 read(1)` 只会给您第一个字符。

关于python tty.setraw Ctrl + C 不起作用(getch),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51509348/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com