I see this code snippet referenced quite a lot during discussions around Python subprocess pipelines. Obligatory link: https://docs.python.org/3.4/library/subprocess.html#replacing-shell-pipeline
Modified slightly:
p1 = subprocess.Popen(['cat'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
p2 = subprocess.Popen(['head', '-n', '1'],
stdin=p1.stdout,
stdout=subprocess.PIPE)
# Allow p1 to receive a SIGPIPE if p2 exits.
p1.stdout.close()
output = p2.communicate()[0]
This shell pipeline is pointless, except to succinctly demonstrate the challenge. Input "abc\ndef\nghi\n" and only "abc\n" should be captured in output.
What is the best way to write data to p1.stdin? I am aware of the input argument to subprocess.Popen.communicate(), but it won't work in a pipeline. Also, the solution needs to handling blocking correctly.
My guess: Reverse engineer the code behind communicate() and create another version for this specific issue. Before I do that, I want to ask if there is a simpler solution of which I am not aware.
You need to call an equivalent of
p1.communicate(b"abc\ndef\nghi\n")andoutput = p2.communicate()[0]concurrently. A portable way to do it is to use threads orasyncio.