2011-06-27 8 views
12

Después de terminar un subproceso ffmpeg, el terminal se arruina: los caracteres mecanografiados son invisibles. La entrada todavía funciona porque los comandos se pueden ejecutar, pero la entrada del teclado no se repite en el terminal.El texto del terminal se vuelve invisible después de terminar el subproceso

Emitiendo el comando de shell reset pone todo nuevamente a la normalidad (o !reset desde dentro de ipython), por lo que una solución al problema es llamar al os.system('reset') dentro del script.

Otras cosas que he intentado: import curses; curses.initscr() antes de generar el subproceso y curses.endwin() después de la terminación, que funcionó un poco pero quebró otras cosas. Otro problema posiblemente relacionado es que después de generar el proceso secundario, el terminal interactivo se vuelve lento y algunas veces no captura los caracteres escritos.

El código para generar el proceso es así:

with open('/tmp/stdout.log', 'w') as o: 
    with open('/tmp/stderr.log', 'w') as e: 
     proc = subprocess.Popen([args], stdout=o, stderr=e) 

Y más tarde para detenerlo:

proc.terminate() 
proc.communicate() 

Qué podría ir mal aquí?

+0

Supongo que tiene algo que ver con 'stdout = o, stderr = e' – warvariuc

+0

El mismo problema existe en django runserver cuando se vuelve a cargar. –

+0

he redirigido stdout y stderr a os.devnull y el problema persiste – wim

Respuesta

11

cambiar el guión por lo que proc.terminate() no se usa. Puede detener un subproceso ffmpeg más cortésmente con

proc.send_signal(signal.SIGINT) 
    proc.wait() 

Esto permite ffmpeg la oportunidad de escribir lo secuencias de escape que necesita para restaurar el terminal.


edición: descubrió más tarde-otro consejo para hacer ffmpeg se comportan mejor con Popen es proporcionar un subprocess.PIPE o open(os.devnull) en el mango stdin. De lo contrario, parece tratar de obtener información del archivo stdin del padre que puede causar un comportamiento extraño en el terminal. Un proceso de ejecución de ffmpeg está escuchando '?' y la entrada 'q' en stdin.

+0

set stdin to 'open (os.devnull)' funciona – mononoke

2

¿se comunica con el subproceso? en ese caso, usaría pexpect, lo que hace que ese tipo de configuración sea muy simple, ¿quizás debe esperar a que termine el comando? es decir

p = subprocess.Popen(argv, stdout=o, stderr=e) 
p.wait() 
if p.returncode != 0: 
     print("problems") 

eso es lo que yo uso en un guión dvd2h264 que escribí hace un tiempo, nunca tuvo ningún problema con él, pero no redirigir la entrada estándar/stderr a TMPFILES ..

+0

no hay comunicación realmente interactiva: estoy codificando una transmisión en vivo conectada desde una tarjeta de captura, y la instancia de Popen finaliza cuando una secuencia de comandos recibe un SIGINT (ya sea desde el teclado o desde otro script). También intenté usar proc.send_signal (signal.SIGINT), y esperar medio segundo antes de verificar proc.returncode ... si todavía es None, entonces lo mato con terminate() que creo que usa un SIGTERM – wim

+0

ok, ¿eres capaz? para extraer el código que falla, es decir, hacer un ejemplo 'hallo fail' que podría probar? la causa de la falla del terminal debe ser que una secuencia de escape se escriba en stdout, pero para ver qué sucede, un pequeño fragmento de código que produce el error ayudaría. – bjarneh

+0

gracias, he visto casos en los que puede escribir en texto coloreado usando secuencias de escape, por lo que me ha dado algunas ideas para probar - tal vez necesito 'volver a escanear' para regresar al texto sin formato. desafortunadamente no puedo proporcionarle un ejemplo de falla constante, porque parece ser un problema intermitente y es posible que necesite la misma tarjeta de captura para reproducirlo – wim

1

os.system('stty sane') funcionó para mí. Restablece las configuraciones haciendo el eco invisible.

Cuestiones relacionadas