【发布时间】:2016-01-13 21:45:26
【问题描述】:
已经有很多答案可以解决如何做这个一般的事情,但我的主要问题是为什么这种方法不起作用?
我正在尝试从子进程“直播”标准输出和标准错误。我可以这样做:
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 不起作用?
【问题讨论】:
-
您是否希望在 stdout 和 stderr 行之间始终保持一一对应关系?您正在尝试成对排列。
-
如果 stdout/stderr 不产生相同数量的输出(大于阈值),这两个代码示例都可能导致死锁
-
@J.F.Sebastian 怎么样?我已经对其进行了测试,它似乎可以工作。你能举例说明死锁是如何发生的吗?
-
@NickHumrich:如果您无法创建导致死锁的示例,请提出单独的问题。
标签: python python-3.x subprocess