我有5个进程 p1,p2,...,p5
,我想将一些数据写入p1的标准输入,将p1的输出导向到p2的标准输入,最后从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"], stdin=p1.stdout, 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并终止。因此,在前一个进程完成处理之前,管道中的后续进程不应该终止。
编辑2:我知道我也可以使用
command = 'bash -c "p1 | p2 | p3 | p4 | p5"'
proc = Popen([command], shell=True)
out, err = proc.communicate(input=indata)
print out
但我的主要兴趣是了解如何在纯Python代码中链式使用管道。
pipes
模块(https://docs.python.org/2/library/pipes.html),并相应地为另一个问题添加了答案。它看起来比其他解决方案要好得多。 - Kyle Strand