2009-03-29 11 views
6

Espero que esta sea una pregunta simple de Python.¿por qué no subprocesamos.Popen (...) siempre regresa?

Cuando intento lo siguiente en el intérprete de Python:

>>> import process 
>>> def test(cmd): 
... p = subprocess.Popen(cmd) 
... 
>>> test(['ls', '-l']) 

Se ejecutará el ls -l, pero yo tenga que pulsar "retorno" para obtener un nuevo prompt >>>.

Sin embargo, cuando intento el siguiente:

>>> import process 
>>> def test(cmd): 
... p = subprocess.Popen(cmd) 
... p.wait() 
... 
>>> test(['ls', '-l']) 

Entonces el ls -l se ejecutará con un prompt >>> inmediato presente.

Otra variación:

>>> import process 
>>> def test(cmd): 
... p = subprocess.Popen(cmd, stdout=subprocess.PIPE) 
... 
>>> test(['ls', '-l']) 

Esto me dará una nueva petición inmediata.

El último ejemplo es el más cercano a lo que deseo. Mi objetivo es lanzar un proceso hijo, esperar a que termine y luego utilizar su stdout en mi proceso principal consultando p.stdout mientras dejo que stderr simplemente imprima donde lo haría de otra manera.

Ahora mismo en mi aplicación actual, la última versión se cuelga en el: p = subprocess.Popen(cmd, stdout=subprocess.PIPE) con o sin un p.wait().

Gracias,

Charlie

Respuesta

7

que pueden haber respondido a mi propia pregunta. Creo que en el último caso, debo leer explícitamente de p.stdout para que mi proceso continúe.

es decir:

p = subprocess.Popen(cmd, stdout=subprocess.PIPE) 
output = p.stdout.readlines() 
.... 

Gracias a todos

8

En la primera variación, test() vuelve inmediatamente después de comenzar el proceso, pero antes de su salida se envía a la consola.

Si mira la salida haga obtenga el mensaje, inmediatamente antes de la salida ls.

>>> test(['ls', '-l']) 
>>> total 0       <----- test() returns, new propmpt 
--rw-r--r-- 1 foo bar 7 Mar 24 17:38 
etc etc 

En la segunda variación, test() está esperando que el proceso termine antes de que vuelva.

En la tercera versión, tiene razón en que puede que tenga que leer en el proceso secundario stdout para que continúe.

0

Simplemente use el método de comunicación(). No es necesario que regrese.

>>> test(['ls', '-l']) 
>>> 
>>> def test(cmd): 
... p = subprocess.Popen(cmd).communicate() 
... 
>>> test(['ls', '-l']) 
+1

Sin redireccionar ninguno de los controladores estándar del subcomando, '.communicate()' no hará nada útil. Puede ser mejor reemplazarlo con una llamada 'wait()'. – glglgl

0

Aquí es un comando que pings Google para siempre, por lo que debe ser terminado manualmente para recuperar la salida.

Consulte el subprocess documentation para obtener instrucciones sobre cómo convertir las llamadas al método os.popen() en subproceso completo. Clases de Popen.

host = "www.google.com" 
command = "ping %s -t"%host 

#p = os.popen(command) -- using Popen instead of os.popen() to allow calling terminate() 
p = Popen(command, stdout=subprocess.PIPE) 

time.sleep(5) 
print "term" 
p.terminate() 
pingResultSoFar = p.communicate()[0] # get what has been printed to standard out so far 
print pingResultSoFar 
Cuestiones relacionadas