来自 Popen 的流式输出

Posted

技术标签:

【中文标题】来自 Popen 的流式输出【英文标题】:Streaming output from Popen 【发布时间】:2021-04-01 02:12:38 【问题描述】:

处理完成后,Popen 输出总是以字节数组的形式立即到达,我尝试了几种配置,包括使用标准输出文件。

要创建进度条,我想一一接收输出。在此示例中,只有一个 p.stdout.read() 将所有 1 作为字节数组返回。

Example in Google Colab

# shell.py
import sys, time

for _ in range(5):
    print(1)
    time.sleep(0.5)
    sys.stdout.flush()

# code.py
from subprocess import Popen, PIPE

p = Popen(['python', 'shell.py'],
        stdin = PIPE, stdout = PIPE, stderr = PIPE, shell = False, bufsize=1)

output = p.stdout.read()
while output:
    print('output:', output)
    output = p.stdout.read()

【问题讨论】:

很想知道这是如何工作的。我还尝试将出于相同目的的标准输出发送到文件,然后只是 cating 文件以查看会发生什么。似乎 stdout 没有流式传输到文件,而仅在进程完成时才转储,并且传递 BytesIO 或 StringIO 对象似乎给出了错误 【参考方案1】:

您可以指定 read() 将读取多少字节。如果您在 code.py 中使用 p.stdout.read(1),您的代码将按您的意愿运行。请注意,python 的 print 函数会在 shell.py 的输出中添加换行符,因此 code.py 会打印出来:

output: b'1'
output: b'\n'
output: b'1'
output: b'\n'
output: b'1'
output: b'\n'

另外值得一提的是,这将读取 bytes。如果你想要一个一个的 unicode 字符,你必须自己做一些处理。

【讨论】:

以上是关于来自 Popen 的流式输出的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Popen 同时写入标准输出和日志文件?

subprocess.Popen 和缓冲的进程输出

Python:使用 subprocess.call 获取输出,而不是 Popen [重复]

将标准输出从 subprocess.Popen 保存到文件,并将更多内容写入文件

如何将 gzip 输出重定向到 Popen 标准输入

将popen输出重定向到python中的文件