从子进程连续处理大量的stdout和stderr

时间:2015-02-12 00:10:39

标签: python python-3.x io subprocess

Stack Overflow上有很多关于如何使用子进程,异步IO处理输出以及避免PIPE死锁的好答案。但是有些事情并没有让我沉沦;我需要一些关于如何完成以下内容的指导。

我想从我的python程序运行一个子进程。子进程会产生大量的标准输出,如果情况变坏则会产生一些标准错误。子进程本身大约需要20分钟才能完成。对于生成的输出和错误,我希望能够将其记录到终端,并将其写入日志文件。

做后者很容易。我刚刚打开了两个文件,然后在Popen对象上设置为stdout和stderr。然而,也将输出捕获为线条以便我可以将它们连续打印到终端让我感到烦恼。我以为我可以使用poll()方法连续轮询。尽管如此,我仍然需要将PIPE用于stdout和stderr,并对它们调用read(),这将阻塞直到EOF。

我认为我想要完成的是:

start the subprocess
    while process is still running
        if there are any lines from stdout
           print them and write them to the out log file
        if there are any lines from stderr
           print them and write them to the err log file
        sleep for a little bit

这看起来合情合理吗?如果是这样,有人可以解释如何在不阻塞的情况下实现“if”部分。

由于

1 个答案:

答案 0 :(得分:2)

这是我的select.select版本:

子流程(foo.py):

import time
import sys

def foo(): 
    for i in range(5): 
        print("foo %s" %i, file=sys.stdout, )#flush=True
        sys.stdout.flush()
        time.sleep(7)
foo() 

主要:

import subprocess as sp
import select
proc= sp.Popen(["python", "foo.py"], stderr=sp.PIPE, stdout=sp.PIPE)
last_line = "content"
while last_line: 
    buff = select.select([proc.stdout], [], [], 60)[0][0]
    if not buff:
        print('timed out') 
        break 
    last_line = buff.readline() 
    print(last_line)