Quiero usar subprocess.check_output()con ps -A | grep 'process_name'. Probé varias soluciones, pero hasta ahora nada funcionó. ¿Alguien puede guiarme cómo hacerlo?
Quiero usar subprocess.check_output()con ps -A | grep 'process_name'. Probé varias soluciones, pero hasta ahora nada funcionó. ¿Alguien puede guiarme cómo hacerlo?
Respuestas:
Para usar una tubería con el subprocessmódulo, debe pasar shell=True.
Sin embargo, esto no es realmente aconsejable por varias razones, entre ellas la seguridad. En su lugar, cree los procesos psy por grepseparado, y canalice la salida de uno a otro, así:
ps = subprocess.Popen(('ps', '-A'), stdout=subprocess.PIPE)
output = subprocess.check_output(('grep', 'process_name'), stdin=ps.stdout)
ps.wait()
En su caso particular, sin embargo, la solución simple es llamar subprocess.check_output(('ps', '-A'))y luego str.finden la salida.
shell=True
subprocess.CalledProcessError: Command '('grep', 'process_name')' returned non-zero exit status 1solo significa que grep no encontró nada, por lo que es un comportamiento normal.
ps.wait()para cuando ya tenemos la salida? ps.wait.__doc__espera que el niño termine pero el contenido del niño ya parece estar colocado en la outputvariable
string.find, que ha quedado en desuso a favor str.find(es decir, el método finden los strobjetos).
grepmuere prematuramente; pspuede colgarse indefinidamente si produce una salida suficiente para llenar su búfer de canalización del sistema operativo (porque no ha llamado ps.stdout.close()al padre). Cambie el orden de inicio, para evitarlo
O siempre puede usar el método de comunicación en los objetos de subproceso.
cmd = "ps -A|grep 'process_name'"
ps = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
output = ps.communicate()[0]
print(output)
El método de comunicación devuelve una tupla de la salida estándar y el error estándar.
communicatees mejor que wait. Existe una advertencia de este tipo: "Esto se bloqueará cuando se use stdout = PIPE y / o stderr = PIPE y el proceso secundario genera suficiente salida para una tubería de manera que bloquea la espera de que el búfer de tubería del sistema operativo acepte más datos. Utilice la comunicación () para evitar eso ".
Consulte la documentación sobre la configuración de una tubería mediante el subproceso: http://docs.python.org/2/library/subprocess.html#replacing-shell-pipeline
No he probado el siguiente ejemplo de código, pero debería ser aproximadamente lo que quieres:
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 solución de JKALAVIS es buena, sin embargo, agregaría una mejora para usar shlex en lugar de SHELL = TRUE. a continuación estoy agotando tiempos de consulta
#!/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)
Después de Python 3.5 también puedes usar:
import subprocess
f = open('test.txt', 'w')
process = subprocess.run(['ls', '-la'], stdout=subprocess.PIPE, universal_newlines=True)
f.write(process.stdout)
f.close()
La ejecución del comando está bloqueando y la salida estará en process.stdout .