我的python脚本使用信号 process 模块拦截SIGINT信号以防止过早退出,但是此信号被传递到我用Popen打开的子进程。是否有一些方法可以阻止将此信号传递给子进程,以便在用户按下ctrl-c时也不会过早退出?
答案 0 :(得分:15)
启动子进程时会继承信号处理程序,因此如果使用信号模块忽略SIGINT(signal.signal(signal.SIGINT, signal.SIG_IGN)
),那么您的子进程也会自动进行。
但有两个重要的警告:
因此,如果您需要自定义SIGINT的处理而不是忽略它,您可能希望在生成子进程时暂时忽略SIGINT,然后(重新)设置自定义信号处理程序。
如果您正在尝试捕获SIGINT并设置一个标志,以便您可以在安全点而不是立即退出,请记住,当您到达安全点时,您的代码必须手动清理其后代,因为您的孩子进程及其启动的任何进程都将忽略SIGINT。
答案 1 :(得分:2)
您可以使用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)
答案 2 :(得分:0)
对于 python 2 代码库:子进程已损坏。
正确的是
import subprocess32 as subprocess
<块引用>
这是用于 Python 的 Python 3 子进程模块的向后移植 2.本代码未在Windows或其他非POSIX平台上测试。