捕获子进程输出

26

我学到了在Python中执行命令时,应该使用subprocess模块。 我想要做的是通过ffmpeg对文件进行编码,并监控程序输出,直到文件处理完成。ffmpeg会将进度记录在stderr中。

如果我尝试像这样:

child = subprocess.Popen(command, shell=True, stderr=subprocess.PIPE)
complete = False
while not complete:
    stderr = child.communicate()

    # Get progress
    print "Progress here later"
    if child.poll() is not None:
        complete = True
    time.sleep(2)

在调用child.communicate()后,程序不会继续执行,而是等待命令完成。有没有其他方法可以跟踪输出?

2个回答

27

communicate()方法会阻塞直到子进程返回,所以你循环中的其余代码只会在子进程完成运行后才会被执行。从stderr读取数据也会被阻塞,除非你像下面这样一个字符一个字符地读取:

import subprocess
import sys
child = subprocess.Popen(command, shell=True, stderr=subprocess.PIPE)
while True:
    out = child.stderr.read(1)
    if out == '' and child.poll() != None:
        break
    if out != '':
        sys.stdout.write(out)
        sys.stdout.flush()

这将为您提供实时输出。取自Nadia的答案(在这里)


这里不需要使用 child.poll();你可以在结尾处调用 child.wait()。参考链接:https://dev59.com/iXE85IYBdhLWcg3wkkU8#17698359 - jfs
作为一名追求精益求精的人,*!= None* 最好写成 is not None - Psionman

1

.communicate() "从stdout和stderr读取数据,直到达到文件结尾。等待进程终止。"

相反,您应该能够像普通文件一样从child.stderr中读取。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接