Using the sh module, pipes become function composition:
import sh
output = sh.thirdcmd(sh.mysecondcmd(sh.mycmd("arg1")))
If you want to do it with subprocess without shell = True
, there is an example in the docs which shows how to write shell pipelines using subprocess.Popen
. Note that you are supposed to close the proc.stdout
s so that SIGPIPE
s can be received properly:
import subprocess
proc1 = subprocess.Popen(shlex.split('mycmd arg1'), stdout = subprocess.PIPE)
proc2 = subprocess.Popen(shlex.split('mysecondcmd'), stdin = proc1.PIPE,
stdout = subprocess.PIPE)
proc3 = subprocess.Popen(shlex.split('thirdcmd'), stdin = proc2.PIPE,
stdout = subprocess.PIPE)
# Allow proc1 to receive a SIGPIPE if proc2 exits.
proc1.stdout.close()
# Allow proc2 to receive a SIGPIPE if proc3 exits.
proc2.stdout.close()
out, err = proc3.communicate()
This might look like a lot more work than using shell = True
. The reason why you might want to avoid shell = True
is because it can be a security risk (page down to the "Warning" box), especially if you are running a command supplied by a (potentially malicious) user.