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 subprocessmodulo, devi passare shell=True.
Tuttavia, questo non è davvero consigliabile per vari motivi, non ultimo quello della sicurezza. Invece, crea i processi pse grepseparatamente 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.findsull'output.
shell=True
subprocess.CalledProcessError: Command '('grep', 'process_name')' returned non-zero exit status 1significa 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 outputvariabile
string.find, che è stato deprecato a favore di str.find(cioè, il metodo findsugli stroggetti).
grepmuore prematuramente; pspotrebbe 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.
communicatesia 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)