Python 如何使msvcrt.getch()在mintty中的行为与在cmd中的行为相同?
我正试图在python中通过按键调用函数。当脚本在Windows命令行(cmd.exe)中运行时,一切正常。但通常当我在Windows上时,我使用mintty 在mintty中,应用程序的行为不同。Python 如何使msvcrt.getch()在mintty中的行为与在cmd中的行为相同?,python,getch,mintty,Python,Getch,Mintty,我正试图在python中通过按键调用函数。当脚本在Windows命令行(cmd.exe)中运行时,一切正常。但通常当我在Windows上时,我使用mintty 在mintty中,应用程序的行为不同。getch() 在Windows命令行中: 按键 (我按a键) 你按了:b'a' (应关闭的应用程序) 在明蒂: 按键 (我按a键多次) aaaaaaaaaaaaaa (什么也没发生) 简短的回答是“确保windows python可执行调用包装在winpty调用中” 我有一个类似的挑战,我希望支持一
getch()
在Windows命令行中:
按键
(我按a键)
你按了:b'a'
(应关闭的应用程序)
在明蒂:
按键
(我按a键多次)
aaaaaaaaaaaaaa
(什么也没发生)
简短的回答是“确保windows python可执行调用包装在winpty
调用中”
我有一个类似的挑战,我希望支持一个完全交互式的控制台应用程序,它在unixey环境中使用termios
,在Windows中使用msvcrt
- 它在linux和mac中工作
- 它在windows cmd控制台中工作
- 它适用于时髦的windows bash终端,如VS Code one
- 它在“纯”msys2中工作(python通过pacman安装,编译为在
mintty
中运行,因此支持termios
),但是
- 它在“Git for Windows”的mintty bash窗口中失败,除非调用方在命令前添加“winpty”。。。当它失败的时候,它就失败了!(无法轻松摆脱坏掉的控制台应用程序,因为读取键不起作用)
我在这里看到的最大的挑战是检测失败
到目前为止,我具备以下条件:
- 如果加载了
msvcrt
(我们在windows python中运行)
- 和
os.environ.get('TERM_PROGRAM')==“mintty”
(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 for windows在没有winpty的mintty中运行”
更新:使用Bash可以工作!
值得一提的是,如果您可以在路径中使用bash(如果您试图从python中检测mintty,我想这很可能是真的),那么您可以:
- 调用bash脚本(不使用管道stdin和stdout,也不传递参数
-i
,因此它连接到终端,并使用)
- 依靠mintty的辅助设备属性支持
- 使用
echo-n-e
打印转义序列
- 使用带超时的
read
捕获tty响应
- 使用stderr或exit代码将结果输出到python
bash脚本示例:
echo -n -e '\e[>c';
read -rs -t 0.2 -d "" <$(tty)
echo "Look ma! Secondary device attributes are ${REPLY#?} - now if they start with [>77; then I know I'm in mintty."
echo-n-e'\e[>c';
read-rs-t0.2-d”“简短的回答是“确保windows python可执行调用包装在winpty
调用中”
我有一个类似的挑战,我希望支持一个完全交互式的控制台应用程序,它在unixey环境中使用termios
,在Windows中使用msvcrt
- 它在linux和mac中工作
- 它在windows cmd控制台中工作
- 它适用于时髦的windows bash终端,如VS Code one
- 它在“纯”msys2中工作(python通过pacman安装,编译为在
mintty
中运行,因此支持termios
),但是
- 在“Git for Windows”的mintty bash窗口中,会失败,除非调用方在命令前添加“winpty”……当它失败时,它会失败!(无法轻松摆脱坏掉的控制台应用程序,因为读取键不起作用)
我在这里看到的最大的挑战是检测失败
到目前为止,我具备以下条件:
- 如果加载了
msvcrt
(我们在windows python中运行)
- 和
os.environ.get('TERM_PROGRAM')==“mintty”
(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 for windows在没有winpty的mintty中运行”
更新:使用Bash可以工作!
值得一提的是,如果您可以在路径中使用bash(如果您试图从python中检测mintty,我想这很可能是真的),那么您可以:
- 调用bash脚本(不使用管道stdin和stdout,也不传递参数
-i
,因此它连接到终端,并使用)
- 依靠
echo -n -e '\e[>c';
read -rs -t 0.2 -d "" <$(tty)
echo "Look ma! Secondary device attributes are ${REPLY#?} - now if they start with [>77; then I know I'm in mintty."