捕获子进程输出

发布于 2024-08-26 12:15:12 字数 472 浏览 6 评论 0原文

我了解到,在Python中执行命令时,我应该使用子进程。 我想要实现的是通过 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() 后程序不会继续,并等待命令完成。还有其他方法可以跟踪输出吗?

I learned that when executing commands in Python, I should use subprocess.
What I'm trying to achieve is to encode a file via ffmpeg and observe the program output until the file is done. Ffmpeg logs the progress to stderr.

If I try something like this:

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)

the programm does not continue after calling child.communicate() and waits for the command to complete. Is there any other way to follow the output?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

楠木可依 2024-09-02 12:15:12

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 在此处的回答。

communicate() blocks until the child process returns, so the rest of the lines in your loop will only get executed after the child process has finished running. Reading from stderr will block too, unless you read character by character like so:

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()

This will provide you with real-time output. Taken from Nadia's answer here.

静若繁花 2024-09-02 12:15:12

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

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

.communicate() "Read data from stdout and stderr, until end-of-file is reached. Wait for process to terminate."

Instead, you should be able to just read from child.stderr like an ordinary file.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文