shell=True
is necessary if you aren't going to divide into multiple subprocesses yourself -- in this case, you require a shell to evaluate your command, break it down into individual pipeline components, and launch those components. As typical, a shell takes a string to be parsed in this manner (you could also pass it an array, but anything other than the first entry would simply be extra arguments to the shell, filling in $1
, $2
, etc when used outside single quotes in the script passed as the first array entry):
p = subprocess.Popen("ifconfig | sed '/^$/d' | awk 'NR > 1 { print $2 }'",
shell=True, stdout=subprocess.PIPE)
Alternately, to avoid needing any shell at all, you can connect and launch the processes yourself (which is very much the preferred approach when dealing with untrusted input or security-sensitive scenarios; using a shell at all can cause open you up to security vulnerabilities such as Shellshock):
from subprocess import Popen, PIPE
p1 = Popen(['ifconfig'], stdout=PIPE)
p2 = Popen(['sed', '/^$/d'], stdin=p1.stdout, stdout=PIPE)
p3 = Popen(['awk', 'NR > 1 { print $2 }'], stdin=p2.stdout, stdout=PIPE)
stdout, _ = p3.communicate()