将几个子过程组合在一起

问题描述

| 我有5个进程
p1,p2,...,p5
,我想将一些数据写入p1的stdin,将p1输出到p2 stdin,最后从p5的输出读取最终结果。 到目前为止我尝试过的是:
p1 = Popen([\'p1\'],stdin=PIPE,stdout=PIPE)
p2 = Popen([\'p2\'],stdin=p1.stdout,stdout=PIPE)
...
p5 = Popen([\'p5\'],stdin=p4.stdout,stdout=PIPE)

# write data to stdin
p1.stdin.write(indata)
p1.stdin.close()

# not sure in what order to close the pipes here,if at all

# read output
out = p5.stdout.read()
print out
截断的最后一个代码只是挂起,因为我必须做的读/写操作不正确。 我能够使用
communicate()
和两个进程来工作单个进程,而无需向第一个进程提供任何输入(例如来自Python文档的示例):
output=`dmesg | grep hda`
==>
p1 = Popen([\"dmesg\"],stdout=PIPE)
p2 = Popen([\"grep\",\"hda\"],stdout=PIPE)
p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
output = p2.communicate()[0]
但是我不知道如何在不停止解释器的情况下为第一过程提供输入。 我也可以为此使用bash脚本(我已经写过并且可以工作),但是我想知道如何用Python实现相同的功能。 因此,我想问一下,如何正确地完成所有操作,特别是按什么顺序对管道进行读/写/关闭操作? 如果有的话,我正在使用64位Linux。 编辑:我忘了提到所有进程p1,.. p5消耗它们给定的所有输入,对其进行处理,写入stdout,然后终止。因此,流水线中的下一个进程不应在前一个进程完成处理之前终止。 EDIT2:我知道我也可以使用
command = \'bash -c \"p1 | p2 | p3 | p4 | p5\"\'
proc = Popen([command],shell=True)
out,err = proc.communicate(input=indata)
print out
但是我的主要兴趣是了解如何纯粹在python代码链接管道。     

解决方法

        也许这可以帮助:
import sys
import tempfile
from subprocess import Popen,PIPE


cmd = [sys.executable,\'-c\',\'print raw_input()\']

# Using a temp file to give input data to the subprocess instead of stdin.write to avoid deadlocks.
with tempfile.TemporaryFile() as f:
    f.write(\'foobar\')
    f.seek(0)  # Return at the start of the file so that the subprocess p1 can read what we wrote.
    p1 = Popen(cmd,stdin=f,stdout=PIPE)

p2 = Popen(cmd,stdin=p1.stdout,stdout=PIPE)
p3 = Popen(cmd,stdin=p2.stdout,stdout=PIPE)

# No order needed.
p1.stdout.close()
p2.stdout.close()

# Using communicate() instead of stdout.read to avoid deadlocks. 
print p3.communicate()[0]
输出:
$ python test.py
foobar
希望这会很幸福。