“3way”Python子进程管道:将stdout和stderr发送到两个不同的进程?

2024-04-24 04:19:02 发布

您现在位置:Python中文网/ 问答频道 /正文

“标准”子流程管道技术(例如http://docs.python.org/2/library/subprocess.html#replacing-shell-pipeline)能否“升级”为两条管道?在

# How about
p1 = Popen(["cmd1"], stdout=PIPE, stderr=PIPE)
p2 = Popen(["cmd2"], stdin=p1.stdout)
p3 = Popen(["cmd3"], stdin=p1.stderr)
p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
p1.stderr.close()
#p2.communicate()  # or p3.communicate()?

好吧,这实际上是一个不同的用例,但最接近的起点似乎是管道示例。顺便问一下,p2.communicate()如何在“普通”管道中驱动p1?以下是常规管道供参考:

^{pr2}$

我想我最终感兴趣的是什么样的“过程图”(或者仅仅是树?)可以communicate()支持,但我们将把一般情况留到另一天。在

更新:以下是基线功能。如果没有communicate(),则创建2个线程,从p1.stdout和p2.stdout读取数据。在主过程中,通过p1注入输入。标准写入(). 问题是我们是否可以使用just communicate()来驱动一个1源,2个sink的图


Tags: close标准管道过程stderrstdinstdout流程
2条回答

这里的解决方案是创建两个后台线程,这些线程读取一个进程的输出,然后将其写入多个进程的输入:

targets = [...] # list of processes as returned by Popen()
while True:
    line = p1.readline()
    if line is None: break
    for p in targets:
        p.stdin.write(line)

您可以使用bash的process substitution

from subprocess import check_call

check_call("cmd1 > >(cmd2) 2> >(cmd3)", shell=True, executable="/bin/bash")

它将cmd1的stdout重定向到cmd2,并将{}的stderr重定向到cmd3。在

如果您不想使用bash,那么问题中的代码应该按原样工作,例如:

^{pr2}$

相关问题 更多 >