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 subprocessmoduł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ć psi grepprocesami 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.findwyjście.
shell=True
subprocess.CalledProcessError: Command '('grep', 'process_name')' returned non-zero exit status 1oznacza 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 outputzmiennej
string.find, co zostało przestarzałe na korzyść str.find(tj. Metody findna strobiektach).
grepumrze przedwcześnie; psmoż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.
communicatejest 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)