将几个子过程连接在一起
我有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"], 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消耗所有输入它们,处理它,写入标准输出,然后终止。 因此,管道中的下一个进程在前一个进程完成处理之前不应该终止。
编辑2:我知道我也可以使用
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
希望这可以是好消息。
链接地址: http://www.djcxy.com/p/25327.html