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读取,同时保留顺序