2012-03-12 11 views
6

Estoy tratando de comunicarme con un bot de chat de línea de comando con Python usando el módulo subprocess. (Http://howie.sourceforge.net/ usando el binario compilado Win32, tengo mis razones!)Interacción del subproceso de Python, ¿por qué mi proceso funciona con Popen.communicate, pero no con Popen.stdout.read()?

Esto funciona:

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

Pero Popen.communicate espera a la terminación del proceso (y lo envía EOF ?), Quiero poder interactuar con él. La solución aparente para esta era leer stdout/escritura stdin así:

esto no funciona:

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

(Tenga en cuenta que en realidad estoy usando el código más complejo basado en http://code.activestate.com/recipes/440554/ pero el problema es la mismo.)

El problema es que el segundo enfoque funciona perfectamente para comunicarse con cmd, pero cuando ejecuto el chatbot, nada. Así que mi pregunta es, ¿cómo es esto diferente en la captura de salida para usar Popen.communicate()?

es decir, puedo utilizar el segundo enfoque para usar la línea de comando como de costumbre, hasta que ejecute el chatbot, en cuyo punto dejo de recibir el resultado. Usar el primer enfoque muestra correctamente las primeras líneas de salida del bot, pero no me permite interactuar con él.

Respuesta

9

Una diferencia importante entre los dos es que comunicar() cierra stdin después de enviar los datos. No sé acerca de su caso particular, pero en muchos casos esto significa que si un proceso está esperando el final de la entrada del usuario, lo obtendrá cuando se use comunicar(), y nunca lo obtendrá cuando el código se bloquee. read() o readline().

Pruebe agregar Popen.stdin.close() primero y vea si afecta su caso.

+0

Por qué gracias, el cierre de stdin permitió que el chatbot comenzara exactamente como lo hizo 'Popen.communicate', aunque ahora tengo el problema de que necesito poder seguir hablándole ... – SudoNhim

+0

Tal vez su aplicación es línea de lectura por línea, en cuyo caso puede enviar solo líneas para que responda? ¿Cuál es la tarea exacta que estás tratando de lograr? – vmalloc

+0

¿Pero cómo puedo enviarlo entrada una vez que se ha cerrado el stdin? Deseo poder enviar y recibir línea por línea – SudoNhim

3

Si desea interactuar con el programa después de enviar el EOF, en lugar de usar Popen.stdin.close(), puede enviar manualmente el carácter de fin de archivo de línea de comandos, que tiene el mismo efecto pero deja abierto el stdin.

En Python la secuencia de escape de este personaje es '\x1a'.

Cuestiones relacionadas