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

标签 python python-3.x subprocess

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

我正在尝试从子进程“实时传输”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)

这给了我结果:

b'hello world\n'
b'rm: cannot remove \xe2\x80\x98blarg223\xe2\x80\x99: No such file or directory\n'

然而,这会导致一个问题,因为它实际上只实时流式传输标准输出,然后打印所有错误作为结束。所以我想我可以使用以下方法解决这个问题:

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)

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

最佳答案

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

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

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

关于python 流子进程 stdout 和 stderr zip 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34777660/

相关文章:

python - 尝试创建自定义 Docker 镜像,但在 RUN 步骤期间被问到问题

Python 2.7 和正则表达式 : False if statement returns

python - 列表列表的索引复杂度是多少(例如 list[x][y])

python子进程通信() block

python - python 子进程模块古怪吗?

python - 使用 python 中的代码模块重定向标准输入的输出?

python - float 限制

python - 通过删除第一个元素来修改列表

django - 将数据库同步到 python django

python - SQLite 数据库查询(Python、Bottle)