Ich möchte verwenden subprocess.check_output()
mit ps -A | grep 'process_name'
. Ich habe verschiedene Lösungen ausprobiert, aber bisher hat nichts funktioniert. Kann mir jemand zeigen, wie es geht?
Ich möchte verwenden subprocess.check_output()
mit ps -A | grep 'process_name'
. Ich habe verschiedene Lösungen ausprobiert, aber bisher hat nichts funktioniert. Kann mir jemand zeigen, wie es geht?
Antworten:
Um ein Rohr mit dem subprocess
Modul zu verwenden, müssen Sie passieren shell=True
.
Dies ist jedoch aus verschiedenen Gründen nicht wirklich ratsam, nicht zuletzt aus Sicherheitsgründen. Erstellen Sie stattdessen die ps
und grep
-Prozesse separat und leiten Sie die Ausgabe wie folgt von einer zur anderen weiter:
ps = subprocess.Popen(('ps', '-A'), stdout=subprocess.PIPE)
output = subprocess.check_output(('grep', 'process_name'), stdin=ps.stdout)
ps.wait()
In Ihrem speziellen Fall besteht die einfache Lösung jedoch darin, die Ausgabe aufzurufen subprocess.check_output(('ps', '-A'))
und dann str.find
zu aktivieren.
shell=True
subprocess.CalledProcessError: Command '('grep', 'process_name')' returned non-zero exit status 1
bedeutet nur, dass grep nichts gefunden hat, also ist es normales Verhalten.
ps.wait()
für, wenn wir bereits die Ausgabe haben. ps.wait.__doc__
wartet auf die Beendigung des Kindes, aber der Inhalt des Kindes scheint bereits in der output
Variablen platziert zu sein
string.find
, was zugunsten von str.find
(dh der Methode find
für str
Objekte) veraltet ist .
grep
vorzeitig stirbt; ps
kann auf unbestimmte Zeit hängen bleiben, wenn es genügend Ausgabe erzeugt, um seinen OS-Pipe-Puffer zu füllen (weil Sie ps.stdout.close()
das übergeordnete Element nicht aufgerufen haben ). Tauschen Sie die Startreihenfolge aus, um dies zu vermeiden
Oder Sie können die Kommunikationsmethode immer für die Unterprozessobjekte verwenden.
cmd = "ps -A|grep 'process_name'"
ps = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
output = ps.communicate()[0]
print(output)
Die Kommunikationsmethode gibt ein Tupel der Standardausgabe und des Standardfehlers zurück.
communicate
ist besser als wait
. Es gibt eine solche Warnung: "Dies führt zu einem Deadlock bei Verwendung von stdout = PIPE und / oder stderr = PIPE, und der untergeordnete Prozess generiert genügend Ausgabe für eine Pipe, sodass das Warten auf den OS-Pipe-Puffer blockiert wird, um weitere Daten zu akzeptieren. Verwenden Sie communic () to vermeide das. "
Weitere Informationen zum Einrichten einer Pipeline mithilfe eines Unterprozesses finden Sie in der Dokumentation: http://docs.python.org/2/library/subprocess.html#replacing-shell-pipeline
Ich habe das folgende Codebeispiel nicht getestet, aber es sollte ungefähr das sein, was Sie wollen:
query = "process_name"
ps_process = Popen(["ps", "-A"], stdout=PIPE)
grep_process = Popen(["grep", query], stdin=ps_process.stdout, stdout=PIPE)
ps_process.stdout.close() # Allow ps_process to receive a SIGPIPE if grep_process exits.
output = grep_process.communicate()[0]
Die JKALAVIS-Lösung ist gut, ich würde jedoch eine Verbesserung hinzufügen, um Shlex anstelle von SHELL = TRUE zu verwenden. unten grep ich die Abfragezeiten aus
#!/bin/python
import subprocess
import shlex
cmd = "dig @8.8.4.4 +notcp www.google.com|grep 'Query'"
ps = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
output = ps.communicate()[0]
print(output)
Sie können die Pipe-Funktionalität in sh.py ausprobieren :
import sh
print sh.grep(sh.ps("-ax"), "process_name")
Nach Python 3.5 können Sie auch Folgendes verwenden:
import subprocess
f = open('test.txt', 'w')
process = subprocess.run(['ls', '-la'], stdout=subprocess.PIPE, universal_newlines=True)
f.write(process.stdout)
f.close()
Die Ausführung des Befehls blockiert und die Ausgabe erfolgt in process.stdout .