About the example found here
output=`dmesg | grep hda`
becomes:
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]
How to expand it to a 3-process pipeline?
Also, I could not find, what the p1.stdout.close() does exactly? What if p1 runs for a long time? will it wait for p1 to finish before applying the close() ?
Must close() come before communicate() ?
Do I understand correctly that before I call communicate(), the pipeline is set up, but "on hold"? Or rather, each process is started parallel right away, but the ones requiring input from the stdin are blocking until communicate() is called?
Consider:
output=`dmesg | grep hda | grep bla`
Maybe something like this:
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]
(the one above crashes with ValueError: I/O operation on closed file
in the current form)
This one does not throw an error, but since I don't understand the close(), it may be a setup for doom sometime later:
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]
Or this:
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]