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 subprocess
mó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 ps
y por grep
separado, 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.find
en la salida.
shell=True
subprocess.CalledProcessError: Command '('grep', 'process_name')' returned non-zero exit status 1
solo 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 output
variable
string.find
, que ha quedado en desuso a favor str.find
(es decir, el método find
en los str
objetos).
grep
muere prematuramente; ps
puede 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.
communicate
es 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 .