2017-07-04 29 views
1

我在Python中调用一个shell脚本fom,它产生了多个子进程。如果两分钟后未完成,我想终止该过程及其所有子项。在subprocess.TimeoutExpired后抛出Python子进程的子节点抛出

有没有什么办法可以做到与subprocess.run或我必须回去使用Popen?由于运行阻塞,我无法将pid保存在某个地方,以额外的命令杀死孩子。一个简短的代码示例:

try: 
    subprocess.run(["my_shell_script"], stderr=subprocess.STDOUT, timeout=120) 
except subprocess.TimeoutExpired:                  
    print("Timeout during execution") 
+1

是,'popen'是首选。请注意,杀死孩子的孩子不是必须的(取决于'my_shell_script')。他们可以分离。 – freakish

+0

在我的情况下,我绝对希望他们遇难,因为他们产生很高的负载。我可能会回复使用Popen并为我的进程获得一个pid以杀死进程组。 – Raptor

回答

0

从文档报价:

subprocess.run - 这不捕获标准输出或默认标准错误。为此,请将PIPE传递给stdout和/或stderr参数。

如果您不想使用Popen(),则不必使用Popen()。模块中的其他功能,例如.call(),.Popen()。

有三个'文件'流:stdin用于输入,stdout和stderr用于输出。应用程序决定在哪里写什么;通常将错误和诊断信息标记为stderr,其余标记为stdout。要捕获这些输出中的任何一个的输出,请指定subprocess.PIPE参数,以便将'流'重定向到您的程序中。

超时后杀子过程:

import os 
import signal 
import subprocess 

try: 
    proc = subprocess.Popen(["ls", "-l"], stdout=PIPE, stderr=PIPE, timeout=120) 
except subprocess.TimeoutExpired: 
    os.kill(proc.pid, signal.SIGTERM) 
+0

但是,这是如何帮助我杀死子进程的子进程呢?正如您在示例中所看到的,我已经捕获了stderr。 – Raptor

+0

在答案中编辑。 – Tanu

+0

但不称为进程组。在这种情况下'proc.terminate()'更便携(windows) –