不知道具体细节,但最好的方法仍然是用信号捕获错误(甚至可能是所有错误)并终止那里的任何剩余进程。
import signal
import sys
import subprocess
import os
def signal_handler(signal, frame):
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
a = subprocess.check_output(["ls", "-l"], stderr=subprocess.STDOUT)
while 1:
pass # Press Ctrl-C (breaks the application and is catched by signal_handler()
这只是一个模型,你需要捕捉的不仅仅是 SIGINT,但这个想法可能会让你开始,你还需要以某种方式检查生成的进程。
http://docs.python.org/2/library/os.html#os.kill
http://docs.python.org/2/library/subprocess.html#subprocess.Popen.pid
http://docs.python.org/2/library/subprocess.html#subprocess.Popen.kill
我建议重写 check_output 的个性化版本,因为我刚刚意识到 check_output 实际上只是用于简单的调试等,因为在执行过程中你不能与它进行太多交互..
重写 check_output:
from subprocess import Popen, PIPE, STDOUT
from time import sleep, time
def checkOutput(cmd):
a = Popen('ls -l', shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT)
print(a.pid)
start = time()
while a.poll() == None or time()-start <= 30: #30 sec grace period
sleep(0.25)
if a.poll() == None:
print('Still running, killing')
a.kill()
else:
print('exit code:',a.poll())
output = a.stdout.read()
a.stdout.close()
a.stdin.close()
return output
然后随心所欲地使用它,也许将活动执行存储在一个临时变量中,并在退出时用信号或其他拦截主循环错误/关闭的方式终止它们。
最后,您仍然需要在主应用程序中捕获终止以安全地杀死任何孩子,解决此问题的最佳方法是使用 try & except 或 signal。