Te sugerimos que revises esta solución en un ambiente controlado antes de pasarlo a producción, un saludo.
Solución:
Popen.communicate()
es un método auxiliar que realiza una única escritura de datos en stdin
y crea hilos para extraer datos de stdout
y stderr
. Cierra stdin
cuando termine de escribir datos y lea stdout
y stderr
hasta que esos caños se cierren. No puedes hacer un segundo communicate
porque el niño ya ha salido cuando regresa.
Una sesión interactiva con un proceso hijo es bastante más complicada.
Un problema es si el proceso hijo incluso reconoce que debería ser interactivo. En las bibliotecas C que la mayoría de los programas de línea de comandos utilizan para la interacción, los programas que se ejecutan desde terminales (por ejemplo, una consola de Linux o una pseudo-terminal “pty”) son interactivos y vacían su salida con frecuencia, pero los que se ejecutan desde otros programas a través de PIPES no son interactivos y vacían su salida con poca frecuencia.
Otra es cómo debe leer y procesar stdout
y stderr
sin estancamiento. Por ejemplo, si bloquea la lectura stdout
pero stderr
llena su pipa, el niño se detendrá y usted quedará atascado. Puede usar subprocesos para extraer ambos en búferes internos.
Otro más es cómo tratas a un niño que sale inesperadamente.
Para sistemas “unixy” como linux y OSX, el pexpect
El módulo está escrito para manejar las complejidades de un proceso secundario interactivo. Para Windows, no hay una buena herramienta que yo sepa para hacerlo.
Esta respuesta debe atribuirse a @JFSebastian. ! Gracias por los comentarios!
El siguiente código obtuvo mi comportamiento esperado:
import pexpect
analyzer = pexpect.spawn('hfst-lookup analyser-gt-desc.hfstol', encoding='utf-8')
analyzer.expect('> ')
for word in ['слово', 'сработай']:
print('Trying', word, '...')
analyzer.sendline(word)
analyzer.expect('> ')
print(analyzer.before)
Siempre que desee enviar una entrada al proceso, utilice proc.stdin.write()
. Siempre que desee obtener resultados del proceso, utilice proc.stdout.read()
. Ambas cosas stdin
y stdout
los argumentos para el constructor deben establecerse en PIPE
.
Recuerda algo, que te brindamos la opción de valorar este artículo si te ayudó.