2016-07-14 16 views
0

Ich wollte ein bash Befehl auszuführen innerhalb Python und erhalten die Ausgabe:einen bash Befehl mit Rohr aus Python

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

I bereits versucht:

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

und Dividieren der Prozess in kleinere diejenigen:

p1 und p2 und p1 Pass Ausgang p2, aber das funktioniert nicht

Wie kann ich es tun?

+0

Was meinen Sie mit "nicht funktioniert"? Erhalten Sie eine Fehlermeldung? Passt die Ausgabe nicht zusammen? –

+0

Sie * müssen * entweder 'shell = True' verwenden, oder die Division in kleinere Dinge, und machen Sie es richtig. –

+0

... und wenn Sie nicht zeigen, wie Sie das letztere tun, wie können wir sagen, ob Sie es richtig machen? –

Antwort

2

shell=True ist erforderlich, wenn Sie sich nicht selbst in mehrere Unterprozesse aufteilen möchten. In diesem Fall benötigen Sie eine Shell, um Ihren Befehl auszuwerten, ihn in einzelne Pipeline-Komponenten aufzuteilen und diese Komponenten zu starten. Wie üblich, verwendet eine Shell eine Zeichenfolge, die auf diese Weise geparst werden soll (Sie könnten ihr auch ein Array übergeben, aber alles andere als der erste Eintrag wären einfach zusätzliche Argumente für die Shell, die $1, $2 usw. ausfüllen, wenn sie außerhalb von single verwendet werden Zitate im Skript als der erste Array-Eintrag übergeben):

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

Alternativ jede Schale überhaupt zu vermeiden, benötigen, können Sie die Prozesse selbst (das ist sehr viel der bevorzugte Ansatz verbinden und starten Sie beim Umgang Mit nicht vertrauenswürdigen Eingaben oder sicherheitsrelevanten Szenarien kann die Verwendung einer Shell dazu führen, dass Sie Sicherheitslücken wie Shellshock haben:

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()