Voglio usare subprocess.check_output()
con ps -A | grep 'process_name'
. Ho provato varie soluzioni ma finora niente ha funzionato. Qualcuno può guidarmi come farlo?
Voglio usare subprocess.check_output()
con ps -A | grep 'process_name'
. Ho provato varie soluzioni ma finora niente ha funzionato. Qualcuno può guidarmi come farlo?
Risposte:
Per usare una pipe con il subprocess
modulo, devi passare shell=True
.
Tuttavia, questo non è davvero consigliabile per vari motivi, non ultimo quello della sicurezza. Invece, crea i processi ps
e grep
separatamente e convoglia l'output dall'uno all'altro, in questo modo:
ps = subprocess.Popen(('ps', '-A'), stdout=subprocess.PIPE)
output = subprocess.check_output(('grep', 'process_name'), stdin=ps.stdout)
ps.wait()
Nel tuo caso particolare, tuttavia, la soluzione semplice è chiamare subprocess.check_output(('ps', '-A'))
e quindi str.find
sull'output.
shell=True
subprocess.CalledProcessError: Command '('grep', 'process_name')' returned non-zero exit status 1
significa semplicemente che non è stato trovato nulla da grep, quindi è un comportamento normale.
ps.wait()
per quando abbiamo già l'output. ps.wait.__doc__
attende che il bambino termini, ma il contenuto del bambino sembra già inserito nella output
variabile
string.find
, che è stato deprecato a favore di str.find
(cioè, il metodo find
sugli str
oggetti).
grep
muore prematuramente; ps
potrebbe bloccarsi indefinitamente se produce abbastanza output per riempire il suo buffer di pipe del sistema operativo (perché non hai chiamato ps.stdout.close()
nel padre). Scambia l'ordine di partenza, per evitarlo
In alternativa, è sempre possibile utilizzare il metodo di comunicazione sugli oggetti sottoprocesso.
cmd = "ps -A|grep 'process_name'"
ps = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
output = ps.communicate()[0]
print(output)
Il metodo di comunicazione restituisce una tupla dell'output standard e dell'errore standard.
communicate
sia meglio di wait
. Esiste tale avviso: "Questo si bloccherà quando si utilizza stdout = PIPE e / o stderr = PIPE e il processo figlio genera un output sufficiente per una pipe in modo tale da bloccare l'attesa del buffer della pipe del sistema operativo per accettare più dati. Utilizzare communic () per evitatelo ".
Consulta la documentazione sulla configurazione di una pipeline tramite sottoprocesso: http://docs.python.org/2/library/subprocess.html#replacing-shell-pipeline
Non ho testato il seguente esempio di codice ma dovrebbe essere più o meno quello che vuoi:
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]
La soluzione JKALAVIS è buona, tuttavia aggiungerei un miglioramento per usare shlex invece di SHELL = TRUE. di seguito im grepping out Query times
#!/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)