0

I wanted to execute a bash command from within python and get the output:

ifconfig | sed '/^$/d' | awk 'NR > 1 { print $2 }'

I already tried:

p =subprocess.Popen(["ifconfig | sed '/^$/d' | awk 'NR > 1 { print $2 }'"], stdout = PIPE.)
out = p.communicate()

and dividing the process into smaller ones:

p1 and p2 and pass p1 output to p2 but this is not working

how can I do it?

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
user2480602
  • 37
  • 1
  • 6
  • What do you mean by 'not working'? Do you get an error message? Does the output not match up? – Akshat Mahajan Jul 14 '16 at 16:56
  • You *either* need to use `shell=True`, or the divide-into-smaller-ones thing, and do it right. – Charles Duffy Jul 14 '16 at 16:56
  • ...and if you aren't showing how you're doing the latter, how can we tell if you're doing it right? – Charles Duffy Jul 14 '16 at 16:56
  • BTW, using `ifconfig` isn't good form -- on Linux, that tool hasn't been actively maintained for the better part of a decade now; the `ip` tool shipped with `iproute2` is the modern, maintained, aware-of-recent-kernel-changes alternative. – Charles Duffy Jul 14 '16 at 16:58

1 Answers1

2

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()
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441