关于示例found here
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]
如何将其扩展为3流程管道?
另外,我找不到,p1.stdout.close()到底是做什么的?如果p1运行很长时间怎么办?在应用close()之前它会等待p1完成吗?
必须在沟通()之前关闭()?
我是否正确理解在调用communication()之前,管道已设置,但“保持”?或者更确切地说,每个进程都是立即并行启动的,但是需要从stdin输入的进程才会阻塞,直到调用了communic()?
考虑:
output=`dmesg | grep hda | grep bla`
也许是这样的:
p1 = Popen(["dmesg"], stdout=PIPE)
p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits.
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
p2.stdout.close() # Allow p2 to receive a SIGPIPE if p3 exits.
p3 = Popen(["grep", "bla"], stdin=p2.stdout, stdout=PIPE)
output = p3.communicate()[0]
(上面的那个以当前形式与ValueError: I/O operation on closed file
崩溃)
这个不会抛出错误,但由于我不理解close(),它可能会在以后的某个时间设置为doom:
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.
p3 = Popen(["grep", "bla"], stdin=p2.stdout, stdout=PIPE)
p2.stdout.close() # Allow p2 to receive a SIGPIPE if p3 exits.
output = p3.communicate()[0]
或者这个:
p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
p3 = Popen(["grep", "bla"], stdin=p2.stdout, stdout=PIPE)
p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits.
p2.stdout.close() # Allow p2 to receive a SIGPIPE if p3 exits.
output = p3.communicate()[0]
答案 0 :(得分:0)
根据https://docs.python.org/2/library/subprocess.html的python文档项17.1.4.2,在启动p2之后调用p1.stdout.close()非常重要,以便p1在p1之前退出时接收SIGPIPE。 同样,也应在启动p3后调用p2.stdout.close()。
How to handle a broken pipe (SIGPIPE) in python?解释了如何处理损坏的管道(SIGPIPE)。