如何在 python 退出时防止 bash 中的按键执行
How to prevent keypress execution in bash on python exit
我正在使用 keyboard
包来捕获 python 程序中的关键事件。使用以下内容获取这个简单的脚本:
import keyboard
while True:
try:
if keyboard.is_pressed('ESC'):
break
else:
pass
except:
break
当我在终端中 运行 这个脚本时,它的行为符合预期,直到程序关闭,此时我输入的所有内容都作为 shell 命令输入到 bash 终端。这可能很危险,因为输入的每一行都有可能对系统产生不利影响。
对此有任何建议的解决方法吗?首选纯 python 解决方案,但 bash 中的脚本初始化参数是合适的。
如果您 运行正在 linux 上,您可以使用 exec
到 运行 您的程序。使用 exec 使程序接管终端。这样当程序完成时,就不会再向终端写入任何内容。
如果您正在使用 windows 或只是想要一个纯粹的 python 答案,您可以使用以下代码做同样的事情并退出程序。
import os, signal
os.kill(os.getppid(), signal.SIGHUP)
您正在使用全局键盘钩子读取单个终端的输入。这是一个糟糕的设计,因为它会监视用户可能对其他程序意味着的事件,它会阻止您的程序像普通终端程序一样工作(例如,它不会 运行 而不是 ssh
),并且由于你不触摸你自己的输入队列你会看到重复的输入(正如你所发现的)。
更好的解决方案是将 tty 设置为原始模式,并继续读取单个按键,直到您想要退出
#!/usr/bin/env python3
import termios, tty, sys
# Save terminal settings
old = termios.tcgetattr(0)
# Disable buffering
tty.setcbreak(0)
# Read until Esc
while sys.stdin.read(1) != "\x1B":
pass
# Set the terminal settings back
termios.tcsetattr(0, termios.TCSANOW, old)
如果您喜欢自己的设计,可以在退出前刷新输入队列:
import termios
termios.tcflush(0, termios.TCIFLUSH)
我正在使用 keyboard
包来捕获 python 程序中的关键事件。使用以下内容获取这个简单的脚本:
import keyboard
while True:
try:
if keyboard.is_pressed('ESC'):
break
else:
pass
except:
break
当我在终端中 运行 这个脚本时,它的行为符合预期,直到程序关闭,此时我输入的所有内容都作为 shell 命令输入到 bash 终端。这可能很危险,因为输入的每一行都有可能对系统产生不利影响。
对此有任何建议的解决方法吗?首选纯 python 解决方案,但 bash 中的脚本初始化参数是合适的。
如果您 运行正在 linux 上,您可以使用 exec
到 运行 您的程序。使用 exec 使程序接管终端。这样当程序完成时,就不会再向终端写入任何内容。
如果您正在使用 windows 或只是想要一个纯粹的 python 答案,您可以使用以下代码做同样的事情并退出程序。
import os, signal
os.kill(os.getppid(), signal.SIGHUP)
您正在使用全局键盘钩子读取单个终端的输入。这是一个糟糕的设计,因为它会监视用户可能对其他程序意味着的事件,它会阻止您的程序像普通终端程序一样工作(例如,它不会 运行 而不是 ssh
),并且由于你不触摸你自己的输入队列你会看到重复的输入(正如你所发现的)。
更好的解决方案是将 tty 设置为原始模式,并继续读取单个按键,直到您想要退出
#!/usr/bin/env python3
import termios, tty, sys
# Save terminal settings
old = termios.tcgetattr(0)
# Disable buffering
tty.setcbreak(0)
# Read until Esc
while sys.stdin.read(1) != "\x1B":
pass
# Set the terminal settings back
termios.tcsetattr(0, termios.TCSANOW, old)
如果您喜欢自己的设计,可以在退出前刷新输入队列:
import termios
termios.tcflush(0, termios.TCIFLUSH)