Python capture subprocess output after termination

走远了吗. 提交于 2019-11-29 11:53:22

You need to use Popen and subprocess.PIPE in order to catch the process output when timeout expires. In particular Popen.communicate is what you need. Here is an example

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)

This will print the process output up to the time out expiration.

If you cannot use timeout for whatever reason (one being a too old python version), here's my solution, which works with whatever python version:

  • create a thread that first waits then kills the subprocess object
  • in the main thread, read the lines in a loop.

I'm using a python subprocess, running with the -u (unbuffered) option:

transmitter.py: (test program which prints "hello xx" every 1/10th second)

import time

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

the program itself (timeout set to 1.5 second):

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))

In the end, after timeout, the program prints:

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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!