我希望在Python中启动一个运行时间相当长的子进程,并希望能够使用^C终止它。但是,按^C会导致父进程接收KeyboardInterrupt并终止(有时会将sleep作为一个已失效的进程)。
import subprocess
subprocess.call("sleep 100".split())如何使按下^C只终止sleep进程(就像在shell命令行中那样),并允许父进程继续?我相信我尝试过将preexec_fn、start_new_session和shell标志组合到call中,但没有成功。
编辑:我知道可以将subprocess调用封装在try-catch块中,而忽略键盘中断;但我不想这样做。我的问题是:键盘中断应该杀死sleep,并且应该是它的结束。为什么会像以前一样被传播到父母身上。还是sleep进程从来都不是接收中断的那个进程?如果没有,我将如何使它成为前台过程?
同样,我试图模仿命令行的父-子关系。如果我要在命令行上执行等效的操作,我可以不需要额外的处理就可以逃脱。
发布于 2016-07-22 08:10:57
正如雅各布所建议的那样,有一种方法(多亏了同事)就是处理信号,并将信号传递给孩子。所以像这样的包装应该是:
import signal
import subprocess
def run_cmd(cmd, **kwargs):
try:
p = None
# Register handler to pass keyboard interrupt to the subprocess
def handler(sig, frame):
if p:
p.send_signal(signal.SIGINT)
else:
raise KeyboardInterrupt
signal.signal(signal.SIGINT, handler)
p = subprocess.Popen(cmd, **kwargs)
if p.wait():
raise Exception(cmd[0] + " failed")
finally:
# Reset handler
signal.signal(signal.SIGINT, signal.SIG_DFL)发布于 2016-07-20 18:22:26
使用signal捕获SIGINT,并使信号处理程序终止子进程。
有关更多信息(如果是Python2.x的话),请看这个:
发布于 2016-07-20 18:24:33
不确定这是否是一个解决办法,但它可以正常工作(至少在不同处理CTRL+C的Windows上是这样的)
import subprocess
try:
subprocess.call(r"C:\msys64\usr\bin\sleep 100".split())
except KeyboardInterrupt:
print("** BREAK **")
print("continuing the python program")处决:
K:\jff\data\python>dummy_wait.py
** BREAK **
continuing the python programhttps://stackoverflow.com/questions/38487972
复制相似问题