2009-03-29 16 views
6

Spero che questa sia una semplice domanda python.perché non sottoprocesso.Popen (...) restituisce sempre?

Quando provo il seguente nell'interprete python:

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

Verrà eseguito il ls -l, ma ho bisogno di colpire "ritorno" per ottenere un nuovo prompt >>>.

Tuttavia, quando provo il seguente:

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

Poi il ls -l viene eseguita con un prompt >>> immediatamente presente.

Un altra variante:

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

Questo mi darà un nuovo prompt immediato.

L'ultimo esempio è il più vicino a quello che voglio. Il mio obiettivo è quello di avviare un processo figlio, attendere che finisca e quindi utilizzare il suo stdout nel mio processo genitore facendo riferimento a p.stdout lasciando allo stderr solo la stampa ovunque esso vada altrimenti.

In questo momento nella mia applicazione effettiva, l'ultima versione del proprio pende al: p = subprocess.Popen(cmd, stdout=subprocess.PIPE) con o senza p.wait().

Grazie,

Charlie

risposta

7

mi possono aver risposto alla mia domanda. Credo che nel caso finale, ho bisogno di leggere esplicitamente da p.stdout affinché il mio processo continui.

cioè:

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

Grazie tutto

8

Nella prima variante, test() ritorna immediatamente dopo l'avvio del processo, ma prima della sua uscita viene inviato alla console.

Se si guarda l'uscita si do ottenere il prompt, immediatamente prima dell'uscita di ls.

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

Nella seconda variante, test() sta aspettando la conclusione del processo prima che ritorni.

Nella terza versione, hai ragione che potresti dover leggere dal processo figlio stdout per continuare.

0

Basta usare il metodo communicate(). Non è necessario tornare.

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

Senza reindirizzare alcuno dei gestori std del comando secondario, '.communicate()' non farà nulla di utile. Potrebbe essere meglio sostituirlo con una chiamata 'wait()'. – glglgl

0

Ecco un comando che ping Google per sempre, quindi deve essere terminato manualmente per recuperare l'output.

Vedere subprocess documentation per istruzioni sulla conversione delle chiamate del metodo os.popen() alle sottoprocessi complete. Classi di risorse.

Problemi correlati