Python监控子进程的stderr和stdout

Posted

技术标签:

【中文标题】Python监控子进程的stderr和stdout【英文标题】:Python monitoring stderr and stdout of a subprocess 【发布时间】:2011-07-07 15:12:07 【问题描述】:

我试图从 python 2.7 中将程序 (HandBreakCLI) 作为子进程或线程启动。我已经开始了,但我不知道如何监控它的标准错误和标准输出。

程序将其状态(完成百分比)和有关编码的信息分别输出到 stderr 和 stdout。我希望能够定期从适当的流中检索完成的百分比。

我尝试调用 subprocess.Popen 并将 stderr 和 stdout 设置为 PIPE 并使用 subprocess.communicate,但它会等待进程被杀死或完成,然后检索输出。对我没有多大好处。

我已经把它作为一个线程启动并运行,但据我所知,我最终仍然需要调用 subprocess.Popen 来执行程序并运行到同一堵墙。

我这样做的方式是否正确?我还有哪些其他选择或如何使其按照描述的方式工作?

【问题讨论】:

communicate() 总是等待进程结束;您必须直接从 stderr 读取。你能发布一些代码吗? 【参考方案1】:

我已经用 ffmpeg 完成了同样的事情。这是相关部分的精简版。 bufsize=1 表示行缓冲,可能不需要。

def Run(command):
    proc = subprocess.Popen(command, bufsize=1,
        stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
        universal_newlines=True)
    return proc

def Trace(proc):
    while proc.poll() is None:
        line = proc.stdout.readline()
        if line:
            # Process output here
            print 'Read line', line

proc = Run([ handbrakePath ] + allOptions)
Trace(proc)

编辑 1: 我注意到子进程(在这种情况下为手刹)需要在行后刷新才能使用它(ffmpeg 确实如此)。

编辑 2: 一些快速测试表明 bufsize=1 可能实际上并不需要。

【讨论】:

除非 OP 没有使用默认值,否则不需要降低 bufsize,尽管将其设置为行缓冲可能是一个好主意:“bufsize 的默认值为 0(无缓冲) 。” docs.python.org/library/subprocess.html 你说得对,我只记得将 bufsize 设置为 1 有一些意义和效果 :) 相应地进行编辑。 有机会,你有线程安全的版本,还是这个线程安全的? :) @naxa:假设proc 不在线程之间共享,我看不到这段代码中固有的任何非线程安全的东西。

以上是关于Python监控子进程的stderr和stdout的主要内容,如果未能解决你的问题,请参考以下文章

Python asyncio子进程连续写入stdin和读取stdout/stderr

python 实时子进程stdout / stderr

Python分别从子进程stdout和stderr读取,同时保留顺序

supervisor安装及其配置

将子进程的 stdout 和 stderr 重定向到两个命名管道(然后从它们读回)

Node.js 使用单独的 stdout 和 stderr 流以交互方式生成子进程