如何使msvcrt.getch()的薄荷味与cmd的行为相同?

时间:2019-10-01 07:23:32

标签: python getch mintty

我正在尝试在python中的按键上调用函数。当脚本在Windows命令行(cmd.exe)中运行时,一切都会按预期工作。但是通常当我在Windows上时,我会使用薄荷糖。

在薄荷方面,应用程序的行为有所不同。 getch()永远阻止该应用程序。

import msvcrt

print("press a key")
char = msvcrt.getch()
print(f"you pressed: {char}")

在Windows命令行中:

  

按一个键

     

(我按a键)

     

您按下:b'a'

     

(应用程序应关闭)

薄荷味:

  

按一个键

     

(我按了多次)

     

aaaaaaaaaaaaaaaa

     

(什么都没发生)

1 个答案:

答案 0 :(得分:0)

简短的答案是“确保将Windows python可执行文件调用包装在winpty调用中”。

我面临类似的挑战,我希望支持一个完全交互式的控制台应用程序,该应用程序在unixey环境中使用termios,在Windows中使用msvcrt

  • 它可在linux和mac上运行,
  • 它在Windows cmd控制台中工作,
  • 它可以在时髦的Windows bash终端中使用,例如VS Code,
  • 它可在“纯” msys2中工作(通过pacman安装python,将其编译为在mintty中运行,因此支持termios),但是
  • 在“ Git for Windows”的薄荷重击窗口中,
  • 失败,除非调用者在命令前添加了“ winpty” ...并且失败,则失败很大! (由于读取键不起作用,因此无法轻易退出损坏的控制台应用程序)

我在这里看到的最大的挑战是检测该故障。

到目前为止,我符合以下条件:

  • 如果已加载msvcrt(我们正在Windows python中运行)
  • 还有os.environ.get('TERM_PROGRAM') == "mintty"(是控制台)
  • 还有os.environ.get('TERM') == "xterm"(winpty尚未将终端类型更改为mintty的xterm默认值)
  • 然后引发异常,要求用户使用winpty呼叫

这取决于我系统上一系列奇怪的巧合:

  • mintty的默认“ TERM”设置为“ xterm”(但可配置!)
  • 与最新git捆绑在一起的winpty将其重置为None(以python术语表示)
  • 与msys2捆绑在一起的winpty将其重置为“ xterm-256color”

不幸的是,我认为这种逻辑不是很可靠-winpty和mintty的其他版本的行为可能会有所不同,并且用户可能将mintty的终端类型设置更改为“ xterm”以外的其他内容,在这种情况下,我的脚本会错误地认为一切正常。

我非常希望有一种更可靠的方法来检测我的脚本何时处于“ python中,而不需要winpty的情况下以薄荷运行的Windows”。