Chcę używać subprocess.check_output()
z ps -A | grep 'process_name'
. Próbowałem różnych rozwiązań, ale jak dotąd nic nie działało. Czy ktoś może mi pomóc, jak to zrobić?
Chcę używać subprocess.check_output()
z ps -A | grep 'process_name'
. Próbowałem różnych rozwiązań, ale jak dotąd nic nie działało. Czy ktoś może mi pomóc, jak to zrobić?
Odpowiedzi:
Aby użyć rury z subprocess
modułem, musisz przejść shell=True
.
Nie jest to jednak zalecane z różnych powodów, między innymi z uwagi na bezpieczeństwo. Zamiast utworzyć ps
i grep
procesami oddzielnie, wyjście z rury jedna w drugą, tak jak poniżej:
ps = subprocess.Popen(('ps', '-A'), stdout=subprocess.PIPE)
output = subprocess.check_output(('grep', 'process_name'), stdin=ps.stdout)
ps.wait()
Jednak w twoim konkretnym przypadku prostym rozwiązaniem jest wywołanie, subprocess.check_output(('ps', '-A'))
a następnie str.find
wyjście.
shell=True
subprocess.CalledProcessError: Command '('grep', 'process_name')' returned non-zero exit status 1
oznacza po prostu, że grep nic nie znalazł, więc jest to normalne zachowanie.
ps.wait()
kiedy mamy już dane wyjściowe. ps.wait.__doc__
czeka na zakończenie przez dziecko, ale zawartość dziecka wydaje się już umieszczona w output
zmiennej
string.find
, co zostało przestarzałe na korzyść str.find
(tj. Metody find
na str
obiektach).
grep
umrze przedwcześnie; ps
może zawiesić się na czas nieokreślony, jeśli wygeneruje wystarczającą moc wyjściową do wypełnienia bufora potoku systemu operacyjnego (ponieważ nie wywołano ps.stdout.close()
elementu nadrzędnego). Zamień kolejność początkową, aby tego uniknąć
Lub zawsze możesz użyć metody komunikacji na obiektach podprocesu.
cmd = "ps -A|grep 'process_name'"
ps = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
output = ps.communicate()[0]
print(output)
Metoda komunikacji zwraca krotkę standardowego wyjścia i standardowy błąd.
communicate
jest lepsze niż wait
. Występuje takie ostrzeżenie: „Spowoduje to zakleszczenie przy użyciu stdout = PIPE i / lub stderr = PIPE, a proces potomny generuje wystarczającą moc wyjściową do potoku, tak że blokuje on oczekiwanie na bufor potoku systemu operacyjnego, aby zaakceptować więcej danych. unikaj tego ”.
Zobacz dokumentację dotyczącą konfigurowania potoku za pomocą podprocesu: http://docs.python.org/2/library/subprocess.html#replacing-shell-pipeline
Nie testowałem następującego przykładu kodu, ale powinien on być mniej więcej taki, jak chcesz:
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]
Rozwiązanie JKALAVIS jest dobre, ale dodałbym ulepszenie do używania shlex zamiast SHELL = TRUE. poniżej przedstawiam czasy zapytania
#!/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)