shi*_*ino 13 python subprocess signals sigint intercept
我的python脚本用信号处理模块拦截SIGINT信号以防止过早退出,但是这个信号被传递给我用Popen打开的子进程.是否有一些方法可以防止将此信号传递给子进程,以便在用户按下ctrl-c时也不会过早退出?
Ben*_*Ben 15
启动signal.signal(signal.SIGINT, signal.SIG_IGN)子进程时会继承信号处理程序,因此如果使用信号模块忽略SIGINT(),那么您的子进程也会自动进行.
但有两个重要的警告:
因此,如果您需要自定义SIGINT的处理而不是忽略它,您可能希望在生成子进程时暂时忽略SIGINT,然后(重新)设置自定义信号处理程序.
如果您正在尝试捕获SIGINT并设置一个标志,以便您可以在安全点退出而不是立即退出,请记住,当您到达安全点时,您的代码必须手动清理其后代,因为您的子进程和任何它启动的进程将忽略SIGINT.
您可以使用该tty模块重新分配 ctrl-c 的角色,这允许您操纵信号的分配。但请注意,除非您将它们恢复到修改之前的状态,否则它们将在 shell 的整个会话中持续存在,即使在程序退出后也是如此。
下面是一个简单的代码片段,可帮助您开始存储旧的 tty 设置,将 ctrl-c 重新分配给 ctrl-x,然后在退出时恢复以前的 tty 设置。
import sys
import tty
# Back up previous tty settings
stdin_fileno = sys.stdin.fileno()
old_ttyattr = tty.tcgetattr(stdin_fileno)
try:
print 'Reassigning ctrl-c to ctrl-x'
# Enter raw mode on local tty
tty.setraw(stdin_fileno)
raw_ta = tty.tcgetattr(stdin_fileno)
raw_ta[tty.LFLAG] |= tty.ISIG
raw_ta[tty.OFLAG] |= tty.OPOST | tty.ONLCR
# ^X is the new ^C, set this to 0 to disable it entirely
raw_ta[tty.CC][tty.VINTR] = '\x18'
# Set raw tty as active tty
tty.tcsetattr(stdin_fileno, tty.TCSANOW, raw_ta)
# Dummy program loop
import time
for _ in range(5):
print 'doing stuff'
time.sleep(1)
finally:
print 'Resetting ctrl-c'
# Restore previous tty no matter what
tty.tcsetattr(stdin_fileno, tty.TCSANOW, old_ttyattr)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3997 次 |
| 最近记录: |