python流子进程stdout和stderr zip不起作用

Nic*_*ich 5 python subprocess python-3.x

已经有很多答案可以解决如何执行此常规操作,但是我的主要问题是为什么这种方法行不通?

我正在尝试从子进程“实时流式传输” stdout和stderr。我可以这样做:

import sys
import subprocess

def run_command(cmd):
    process = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)

    for out in iter(process.stdout.readline, b''):
        print(out)

    for err in iter(process.stderr.readline, b''):
        print(err)

run_command(['echo', 'hello', 'world']) # should print hello world
run_command(['rm', 'blarg223'])  # Should print to stderr (file doesnt exist)
Run Code Online (Sandbox Code Playgroud)

这可以给我结果:

b'hello world\n'
b'rm: cannot remove \xe2\x80\x98blarg223\xe2\x80\x99: No such file or directory\n'
Run Code Online (Sandbox Code Playgroud)

但是,这会引起问题,因为它实际上仅实时输出标准输出,然后将所有错误打印到末尾。所以我想我可以使用以下方法解决此问题:

def run_command(cmd):
    process = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)

    for out, err in zip(iter(process.stdout.readline, b''), iter(process.stderr.readline, b'')):
        print(out)
        print(b'Error: ' + err)
Run Code Online (Sandbox Code Playgroud)

但是,这不会产生任何输出。为什么使用zip无效?

Yoa*_*ner 3

当其中一个迭代器完成时 zip 停止。

在您给出的每个示例中,一个流(stdout/stderr)是空的。所以 zip 不会产生任何结果。

要解决此问题,您应该使用 itertools.zip_longest