用子进程终止正在运行的脚本

时间:2020-07-13 19:29:10

标签: python subprocess

我正在使用subprocess执行python脚本。我可以成功运行脚本。

import subprocess
import time

proc = subprocess.Popen(['python', 'test.py', ''], shell=True)
proc.communicate()
time.sleep(10)
proc.terminate()

test.py

import time
while True:
    print("I am inside test.py")
    time.sleep(1)
    

我可以看到消息I am inside test.py每秒打印一次。但是,当脚本仍由proc.terminate()运行时,我无法终止该脚本。

有人可以帮我吗?

2 个答案:

答案 0 :(得分:1)

proc.communicate等待该过程完成,除非您包含超时。您的进程不会退出,并且您没有超时,因此communicate永远不会返回。您可以在通话后使用print进行验证。而是添加一个超时并捕获其异常

import subprocess
import time

proc = subprocess.Popen(['python', 'test.py', ''], shell=True)
try:
    proc.communicate(timeout=10)
except subprocess.TimeoutExpired:
    proc.terminate()

答案 1 :(得分:1)

首先,如果您使用的是subprocess.Popen(),请不要使用列表来传递shell = True的参数,请将命令更改为string,{{ 1}}。

"python test.py"是一种阻塞类方法,它应与进程进行交互,并等待进程终止并设置returncode属性。

由于您的Popen.communicate(input=None, timeout=None)正在运行while循环,因此他将永远不会返回!

您有2个选项可以使您生成的test.py进程超时:

  1. 在中分配timeout关键字参数,例如使用proc方法将过程计时5秒钟。如果过程communicate(timeout=5)proc秒后仍未终止,则会引发timeout。捕获此异常并重试通信不会丢失任何输出(在您的情况下,您不需要子输出,但是我将在下面的示例中提及)。 注意如果TimeoutExpired exception不会杀死子进程,因此为了正确清理行为良好的应用程序,应杀死子进程(timeout expires)并完成通信。 / li>
  2. 使用proc方法,并通过调用方法进行计时。

与超时进行通信

poll

按时间轮询。

try:
    outs, errs = proc.communicate(timeout=15)
except TimeoutExpired:
    proc.kill()
    outs, errs = proc.communicate()