捕获子进程输出

26 投票
2 回答
36710 浏览
提问于 2025-04-15 20:53

我了解到在Python中执行命令时,应该使用subprocess模块。我的目标是通过ffmpeg对一个文件进行编码,并在文件处理完成之前观察程序的输出。ffmpeg会把进度信息记录到错误输出中。

如果我尝试像这样做:

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 个回答

1

.communicate() 是一个方法,它的作用是“从标准输出和标准错误中读取数据,直到文件结束。同时等待这个进程结束。”

不过,你其实可以像读普通文件一样,直接从 child.stderr 中读取数据。

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的回答,详细信息可以在这里找到。

撰写回答