2011-07-21 9 views
19

¿Cómo ejecuto un comando con un conducto | en él?Cómo ejecutar "ps cax | grep something" en Python?

El módulo subproceso parece complejo ...

¿Existe algo así como

output,error = `ps cax | grep something` 

como en shell script?

+0

No haga esto con 'subproceso'. Es mucho más fácil hacer esto con el caparazón. De hecho, esta es la única cosa que el caparazón hace mejor. –

Respuesta

38

Ver Replacing shell pipeline:

import subprocess 

proc1 = subprocess.Popen(['ps', 'cax'], stdout=subprocess.PIPE) 
proc2 = subprocess.Popen(['grep', 'python'], stdin=proc1.stdout, 
         stdout=subprocess.PIPE, stderr=subprocess.PIPE) 

proc1.stdout.close() # Allow proc1 to receive a SIGPIPE if proc2 exits. 
out, err = proc2.communicate() 
print('out: {0}'.format(out)) 
print('err: {0}'.format(err)) 

PS. Usar shell=True puede ser peligroso. Ver por ejemplo the warning en los documentos.


También existe la sh module que puede hacer scripting subproceso en Python mucho más agradable:

import sh 
print(sh.grep(sh.ps("cax"), 'something')) 
+0

Gran referencia al módulo sh, lo recomiendo encarecidamente. –

+0

'sh.grep (sh.ps ('aux', _piped = True), 'algo')' - funcionó para mí –

+0

@unutbu, ¿podría explicar más detalles de por qué 'proc1.stdout.close()' debería llamarse ? – SangminKim

8
import subprocess 

process = subprocess.Popen("ps cax | grep something", 
          shell=True, 
          stdout=subprocess.PIPE, 
          ) 
stdout_list = process.communicate()[0].split('\n') 
+0

algo en grep algo sería una variable, ¿debería construir el string "ps cax | grep something" con variable para ejecutarlo? o hay otra forma de hacerlo? – eugene

+1

http://docs.python.org/library/stdtypes.html#string-formatting o http://docs.python.org/library/string.html#string-formatting. Básicamente, ''grep% s'% variable'. – agf

+3

@Eugene: puede construir la cadena utilizando una variable, pero tenga cuidado de dónde viene la variable. Es decir. asegúrese de que no sea de un usuario que pueda convertir "algo" en '" algo; rm -rf/"'. La construcción de expresiones para ejecutar con shell = True es un posible riesgo de seguridad. –

2
import os 

os.system('ps -cax|grep something') 

Si quieres reemplazar el argumento grep con alguna variable:

os.system('ps -cax|grep '+your_var) 
+2

Eso no le da la salida del comando. –

+0

@Kirk Strauser, ¿no puedes obtener la salida? Lo he probado en intérprete interactivo de python y lo estoy ejecutando como script, funciona como se esperaba (mi versión de Python es 2.7.1, si ayuda) –

+3

'os.system' solo devuelve el código de salida int del subproceso. Si lo está ejecutando en un indicador interactivo y viendo el resultado de ps, es porque ps está escribiendo en stout. Python no está realmente capturando esa salida. Inténtalo tú mismo: ejecuta 'a = os.system ('ls')'. Todavía verá la salida de ls, y 'a' será 0 (asumiendo que ls no falló por alguna razón). –

14

Ya ha aceptado una respuesta, pero:

¿De verdad necesita para usar grep? Me gustaría escribir algo como:

import subprocess 
ps = subprocess.Popen(('ps', 'cax'), stdout=subprocess.PIPE) 
output = ps.communicate()[0] 
for line in output.split('\n'): 
    if 'something' in line: 
     ... 

Esto tiene la ventaja de que no impliquen shell=True y su grado de riesgo, no se bifurca en marcha un proceso grep por separado, y se ve un montón, como el tipo de Python que iba a escribir para procesar objetos similares a archivos de datos.

5

¡Suelta ese subproceso 'ps' y retrocede lentamente! :)

En su lugar, utilice el módulo psutil.

+2

Quiero usar psutil, pero esta respuesta no es muy útil sin mostrar cómo se haría. –

Cuestiones relacionadas