首页 > 解决方案 > 从多个子进程 Popens 一起捕获所有 stderr 数据

问题描述

Popen在 Python 2.7 中通过 stdin/stdout 将多个子进程连接在一起,如下所示:

p1 = Popen(shlex.split(cmd1), stdout=sp.PIPE, stderr=sp.PIPE)
p2 = Popen(shlex.split(cmd2), stdin=p1.stdout, stdout=sp.PIPE, stderr=sp.PIPE)
...
pN = Popen(shlex.split(cmdN), stdin=pN-1.stdout, stdout=sp.PIPE, stderr=sp.PIPE)

stdout, stderr = pN.communicate()

一切都按预期进行得非常顺利;但是我想捕获每个不同进程的标准错误,而目前我只能pN通过pN.communicate(). 我知道每个 stderr 都可以重定向到不同的文件中,但我想知道是否有任何方法可以在 Python 中的最终通信之后和/或之前捕获所有进程的 stderr?

为不同的进程调用通信总是会导致管道损坏。


编辑-1

communicate以与管道中相同的顺序调用每个进程是正确且可接受的解决方案吗?

p1 = Popen(shlex.split(cmd1), stdout=sp.PIPE, stderr=sp.PIPE)
p2 = Popen(shlex.split(cmd2), stdin=p1.stdout, stdout=sp.PIPE, stderr=sp.PIPE)
...
pN = Popen(shlex.split(cmdN), stdin=pN-1.stdout, stdout=sp.PIPE, stderr=sp.PIPE)

stdout1, stderr1 = p1.communicate()
stdout2, stderr2 = p2.communicate()
...
stdoutN, stderrN = pN.communicate()

编辑-2

EDIT 1中提出的解决方案是错误的,因为它communicate在已结束的进程上调用时会产生错误。

目前唯一可行的解​​决方案似乎是重定向所有已处理文件的 stderr 并在确保所有进程终止后读取这些文件:

map(lambda p : p.wait(), (p1, p2, ..., pN))

标签: pythonprocesssubprocesspipepopen

解决方案


推荐阅读