2012-03-12 8 views
6

Sto provando a comunicare con un bot della chat da riga di comando con Python usando il modulo subprocess. (Http://howie.sourceforge.net/ utilizzando il binario compilato win32, ho le mie ragioni!)Interazione del sottoprocesso Python, perché il mio processo funziona con Popen.communicate, ma non Popen.stdout.read()?

Questo funziona:

proc = Popen('Howie/howie.exe', stdout=PIPE,stderr=STDOUT,stdin=PIPE) 
output = proc.communicate() 

Ma Popen.communicate aspetta che il processo per terminare (e lo invia EOF ?), Voglio essere in grado di interagire con esso. La soluzione apparente per questo era da leggere stdout/scrittura stdin in questo modo:

Questo non funziona:

proc = Popen('Howie/howie.exe', stdout=PIPE,stderr=STDOUT,stdin=PIPE) 
while True: print proc.stdout.readline() 

(Si noti che sto effettivamente utilizzando il codice più complesso in base http://code.activestate.com/recipes/440554/ ma il problema è il stesso.)

Il problema è che il secondo approccio funziona perfettamente per comunicare con cmd, ma quando eseguo il chatbot, niente. Quindi la mia domanda è, in che modo è diverso nell'acquisire l'output utilizzando Popen.communicate()?

Ad esempio, posso utilizzare il secondo approccio per utilizzare la riga di comando come normale, fino a quando eseguo il chatbot, a quel punto smetto di ricevere l'output. L'utilizzo del primo approccio visualizza correttamente le prime righe di output del bot, ma non mi consente di interagire con esso.

risposta

9

Una delle principali differenze tra i due è che communicate() chiude lo stdin dopo aver inviato i dati. Non so del tuo caso particolare, ma in molti casi questo significa che se un processo è in attesa della fine dell'input dell'utente, lo otterrà quando viene usato communic(), e non lo otterrà mai quando il codice si blocca su read() o readline().

Provare ad aggiungere prima Popen.stdin.close() e verificare se questo influisce sul caso.

+0

Perché grazie, chiudere stdin ha permesso al chatbot di iniziare esattamente come ha fatto 'Popen.communicate', anche se ora ho il problema che devo essere in grado di continuare a parlarci ... – SudoNhim

+0

Forse la tua applicazione sta leggendo la riga -by-line, nel qual caso è sufficiente inviare singole righe per lasciarlo rispondere? Qual è il compito esatto che stai cercando di raggiungere? – vmalloc

+0

Ma come posso inviarlo in input una volta che stdin è stato chiuso? Desidero essere in grado di inviare e ricevere riga per riga – SudoNhim

3

Se si desidera interagire con il programma dopo aver inviato l'EOF, anziché utilizzare Popen.stdin.close(), è possibile inviare manualmente il carattere di fine riga del comando, che ha lo stesso effetto ma lascia lo stdin aperto.

In Python la sequenza di escape di questo personaggio è '\x1a'.