终止后Python捕获子进程输出

时间:2017-04-20 13:50:16

标签: python timeout subprocess output

我试图在引发TimeoutExpired异常时获取子进程输出(在Windows上)。有什么想法吗?

try:
    proc = subprocess.run(cmd,timeout=3)
except subprocess.TimeoutExpired:
    print(???)

3 个答案:

答案 0 :(得分:5)

您需要使用Popensubprocess.PIPE以便在超时到期时捕获进程输出。特别是Popen.communicate就是你所需要的。 这是一个例子

proc = subprocess.Popen(["ping", "192.168.1.1"],
                        stdout=subprocess.PIPE)

try:
    output, error = proc.communicate(timeout=2)
except subprocess.TimeoutExpired:
    proc.kill()
    output, error = proc.communicate()
    print(output)
    print(error)

这将打印过程输出直到超时。

答案 1 :(得分:1)

如果由于某种原因你不能使用timeout(一个是太旧的python版本),这里是我的解决方案,它适用于任何python版本:

  • 创建一个先等待然后杀死subprocess对象
  • 的线程
  • 在主线程中,读取循环中的行。

我正在使用python子进程,使用-u(无缓冲)选项运行:

  

transmitter.py :(测试程序打印"你好xx"每1/10秒)

import time

i=0
while True:
    print("hello {}".format(i))
    i += 1
    time.sleep(0.1)
  

程序本身(超时设置为1.5秒):

import subprocess,threading,time

def timeout(p,timeout):
    time.sleep(timeout)
    p.kill()

p = subprocess.Popen(["python","-u","transmitter.py"],stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
t = threading.Thread(target=timeout,args=(p,1.5))
t.start()
output = []
for line in p.stdout:
    output.append(line.decode())

t.join()
print("".join(output))

最后,在超时后,程序会打印:

hello 0
hello 1
hello 2
hello 3
hello 4
hello 5
hello 6
hello 7
hello 8
hello 9
hello 10
hello 11
hello 12
hello 13
hello 14

答案 2 :(得分:0)

这是捕获multiprocessing.Process的标准输出的方法

import app
import sys
import io
from multiprocessing import Process


def run_app(some_param):
    sys.stdout = io.TextIOWrapper(open(sys.stdout.fileno(), 'wb', 0), write_through=True)
    app.run()

app_process = Process(target=run_app, args=('some_param',))
app_process.start()
# Use app_process.termninate() for python <= 3.7.
app_process.kill()