【发布时间】:2011-10-31 14:12:34
【问题描述】:
我有一个脚本,它反复运行 Ant 构建文件并将输出刮成可解析的格式。当我使用 Popen 创建子进程时,有一个小时间窗口,按 Ctrl+C 将杀死脚本,但不会杀死运行 Ant 的子进程,留下一个僵尸,它正在打印输出到控制台,只能使用 Task 杀死经理。一旦 Ant 开始打印输出,按 Ctrl+C 总是会杀死我的脚本以及 Ant。有没有办法让按 Ctrl+C 总是会杀死运行 Ant 的子进程而不会留下僵尸?
另外值得注意的是:我有一个 SIGINT 处理程序,它在调用 exit(0) 之前执行一些清理操作。如果我使用os.kill(p.pid, signal.SIGTERM)(不是SIGINT)手动终止处理程序中的子进程,那么我可以在通常会僵尸化的情况下成功终止子进程。但是,一旦 Ant 开始产生输出,当您按 Ctrl+C 时,您会从子进程中获得一个堆栈跟踪,它无法杀死子进程本身,因为我已经杀死了它。
编辑:我的代码看起来像:
p = Popen('ls')
def handle_sig_int(signum, stack_frame):
# perform cleanup
os.kill(p.pid, signal.SIGTERM)
exit(0)
signal.signal(signal.SIGINT, handle_sig_int)
p.wait()
错误触发时会产生以下堆栈跟踪:
File "****.py", line ***, in run_test
p.wait()
File "/usr/lib/python2.5/subprocess.py", line 1122, in wait
pid, sts = os.waitpid(self.pid, 0)
File "****.py", line ***, in handle_sig_int
os.kill(p.pid, signal.SIGTERM)
我通过捕获 p.wait 引发的 OSError 并退出来修复它:
try:
p.wait()
except OSError:
exit('The operation was interrupted by the user')
这似乎在我的绝大多数测试运行中都有效。我偶尔会收到uname: write error: Broken pipe,虽然我不知道是什么原因造成的。如果我在子进程开始显示输出之前按 Ctrl+C 计时,似乎会发生这种情况。
【问题讨论】:
标签: python subprocess