Python监控子进程的stderr和stdout

10 投票
1 回答
5842 浏览
提问于 2025-04-16 12:51

我想在Python 2.7中启动一个程序(HandBreakCLI),希望它能作为一个子进程或线程运行。我已经成功启动了这个程序,但我不知道怎么监控它的错误输出和标准输出。

这个程序会把它的状态(完成百分比)和编码信息分别输出到错误输出和标准输出。我希望能定期从相应的输出流中获取完成的百分比。

我尝试过用subprocess.Popen来启动程序,并把错误输出和标准输出设置为PIPE,然后使用subprocess.communicate,但这样做会一直等到进程结束或者被杀掉,才会获取输出。这对我来说没什么用。

我已经把它作为一个线程运行起来了,但就我所知,我还是需要调用subprocess.Popen来执行这个程序,这样又会遇到同样的问题。

我这样做对吗?还有什么其他的选择,或者我该怎么才能让它按我想的那样工作?

1 个回答

14

我用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:我注意到子进程(在这个例子中是handbrake)在使用这个功能时需要进行刷新(ffmpeg会这样做)。

编辑 2:一些快速测试显示,bufsize=1可能实际上并不是必须的。

撰写回答