Python 难以捕获执行就地状态更新的子流程的输出

Python 难以捕获执行就地状态更新的子流程的输出,python,subprocess,Python,Subprocess,因此,我试图将HandBrakeCLI的输出捕获为Python子进程。这不是stderr的问题,因为每次更新都会在文件中创建一行新行,就像管道一样。然而,在stdout中,HandBrakeCLI进行就地更新,我很难捕获它们。我甚至不知道就地更新叫什么,这使得查找相关提示有点棘手 到目前为止,我提出的唯一解决方案是将标准输出写入一个实际的文件并从中读取,但我更愿意以合理的方式(在内存中)执行此操作 这是可行的,但一定有更好的办法。当尝试使用communicate()或纯proc.stdout.r

因此,我试图将HandBrakeCLI的输出捕获为Python子进程。这不是stderr的问题,因为每次更新都会在文件中创建一行新行,就像管道一样。然而,在stdout中,HandBrakeCLI进行就地更新,我很难捕获它们。我甚至不知道就地更新叫什么,这使得查找相关提示有点棘手

到目前为止,我提出的唯一解决方案是将标准输出写入一个实际的文件并从中读取,但我更愿意以合理的方式(在内存中)执行此操作

这是可行的,但一定有更好的办法。当尝试使用communicate()或纯proc.stdout.read()时,我一无所获

我做错了什么?谢谢

更新 根据@wim建议,我检查了原始输出HandBrakeCLI提供了什么,它看起来像这样:

\rEncoding: task 1 of 1, 0.15 %

处理前缀为a的stdout的最佳方法是什么?

我认为我上面关于使用universal\u newlines=True的评论会起作用

这里有一个名为“inplace_output.py”的就地编写器示例

您可以运行它,并观察它每次重写之前的输出时写入000,然后写入001,等等

下面是一个脚本,它作为子流程运行上述内容,并逐行读取其输出:

import subprocess


cmd = ['python', 'inplace_output.py']

proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, universal_newlines=True)

while True:
    out = proc.stdout.readline()
    print repr(out)
    if len(out) == 0:
        break
如果希望在子流程程序终止时一次收集所有输出,可以将while循环替换为

out, err = proc.communicate()
lines = out.splitlines()

这两种方法对您都有效吗?

就地状态更新如下:编码:任务1/1,5.41%(134.10 fps,平均142.92 fps,ETA 00h25m39s)我想您的问题可能是进度以
\r
终止,从输出读取将基于行,即它将缓冲到
\n
。有一次,我通过读取字节而不是行来解决这个问题,并亲自捕捉到
\r
,但它非常难看。@wim:我相信你是对的。不幸的是,subprocess.stdout似乎没有seek()方法。有哪些选项可用于搜索整个subprocess.stdout缓冲区中的\r\n文件?对于这个,合适的bufsize是什么?谢谢尝试将universal_newlines=True添加到对Popen的调用中。我这样做的方式是使用
stdout=subprocess.PIPE
stdout.read
,因此我不需要搜索。这很困难,因为您必须小心地手动处理通信以避免死锁。如果上面@WarrenWeckesser的建议有帮助的话,最好还是走这条路。。
import subprocess


cmd = ['python', 'inplace_output.py']

proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, universal_newlines=True)

while True:
    out = proc.stdout.readline()
    print repr(out)
    if len(out) == 0:
        break
out, err = proc.communicate()
lines = out.splitlines()