2012-02-22 13 views
18

tengo un caso de querer ejecutar el siguiente comando del shell en Python y obtener la salida,Python: ¿cómo ejecutar comandos de shell con pipe?

echo This_is_a_testing | grep -c test 

que podría utilizar este código Python para ejecutar el comando shell anteriormente en pitón,

>>> import subprocess 
>>> subprocess.check_output("echo This_is_a_testing | grep -c test", shell=True) 
'1\n' 

sin embargo, como no quiero utilizar la opción de "shell = True", probé el siguiente código Python,

>>> import subprocess 
>>> p1 = subprocess.Popen(["echo", "This_is_a_testing"], stdout=subprocess.PIPE) 
>>> p2 = subprocess.Popen(["grep", "-c", "test"], stdin=p1.stdout) 
>>> p1.stdout.close() 
>>> p2.communicate() 
(None, None) 

me pregunto por qué la salida es "Ninguno" como Me he referido a las descripciones en la página web: http://docs.python.org/library/subprocess.html#subprocess.PIPE

¿He perdido algunos puntos en mi código? ¿Alguna sugerencia/idea? Gracias por adelantado.

+0

actualizada relacionada con la respuesta – avasal

+0

: [¿Cómo uso subprocess.Popen para conectar varios procesos por los tubos?] (http://stackoverflow.com/q/295459/4279) – jfs

Respuesta

23

Del manual:

para conseguir que no sea Ninguno en la tupla resultado nada, es necesario dar stdout = PIPE y/o stderr = TUBO

p2 = subprocess.Popen(["grep", "-c", "test"], stdin=p1.stdout, stdout=subprocess.PIPE) 
25

Por favor, busque aquí:

>>> import subprocess 
>>> p1 = subprocess.Popen(["echo", "This_is_a_testing"], stdout=subprocess.PIPE) 
>>> p2 = subprocess.Popen(["grep", "-c", "test"], stdin=p1.stdout) 
>>> 1 
p1.stdout.close() 
>>> p2.communicate() 
(None, None) 
>>> 

aquí obtiene 1 como salida después de escribir p2 = subprocess.Popen(["grep", "-c", "test"], stdin=p1.stdout), No ignore esta salida en el contexto de su pregunta.

Si esto es lo que desea, a continuación, pasar a stdout=subprocess.PIPE como argumento para la segunda Popen:

>>> p1 = subprocess.Popen(["echo", "This_is_a_testing"], stdout=subprocess.PIPE) 
>>> p2 = subprocess.Popen(["grep", "test"], stdin=p1.stdout, stdout=subprocess.PIPE) 
>>> p2.communicate() 
('This_is_a_testing\n', None) 
>>> 
+0

Ahora conozco que para que 'p2.communicate()' funcione, debo agregar 'stdout = subprocess.PIPE' en el código' p2 = ... '. Gracias. – user1129812

+0

¿Cómo puedo obtener un error si ocurre en el resultado de p1? Aquí está mi pregunta, ¿puedes ayudar con eso? http://stackoverflow.com/questions/40467105/how-to-catch-ping-error-with-python –

8
>>> import subprocess 

>>> mycmd=subprocess.getoutput('df -h | grep home | gawk \'{ print $1 }\' | cut -d\'/\' -f3') 

>>> mycmd 

'sda6' 

>>> 
+0

utiliza el shell internamente. OP explícitamente dijo: * "No quiero usar la opción" shell = True "" * – jfs

+1

Gracias. Eso es exactamente lo que estoy buscando cuando busco "*** cómo ejecutar comandos de shell con pipes ***" en Python. – xpt

+2

Tuve que usar commands.getoutput en lugar de subprocess.getoutput para que esto funcione – Anake

1

Mientras que la respuesta aceptada es correcta/de trabajo, otra opción sería utilizar el método Popen.communicate() a pasar algo a un proceso de entrada estándar:

>>> import subprocess 
>>> p2 = subprocess.Popen(["grep", "-c", "test"], stdin=subprocess.PIPE, stdout=subprocess.PIPE) 
>>> p2.communicate("This_is_a_testing") 
('1\n', None) 
>>> print p2.returncode 
0 
>>>> 

Esto resuelve la necesidad de ejecutar otro comando sólo para redirigir está fuera put, si el resultado ya se conoce en el script python.

Sin embargo, communicate tiene el efecto secundario, que espera a que finalice el proceso. Si la ejecución asincrónica es necesaria/deseada con dos procesos, podría ser la mejor opción.

-1

Intenté sh -c "echo 1| grep 1" y acerté. de esta manera: result=subprocess.Popen(['sh','-c',"\"\"echo 1|grep 1\"\""], stdout=subprocess.PIPE).communicate()[0]

Cuestiones relacionadas