la detección de final de salida TTY
-
21-09-2019 - |
Pregunta
Hola Estoy escribiendo un psudo-terminal que puede vivir en un TTY y generar una segunda TTY que es la entrada y salida de los filtros
Estoy escribiendo en Python, por ahora, generando el segundo TTY y la lectura y la escritura es fácil
pero cuando leí, la lectura no termina, espera a más de entrada.
import subprocess
pfd = subprocess.Popen(['/bin/sh'], shell=True,
stdout=subprocess.PIPE, stdin=subprocess.PIPE)
cmd = "ls"
pfd.stdin.write(cmd + '\n')
out = ''
while 1:
c = pfd.stdout.read(1)
if not c: # if end of output (this never happends)
break
if c == '\n': # print line when found
print repr(out)
out = ''
else:
out += c
----------------------------- salidas ----------------- -------
intty $ python intty.py
'intty.py'
'testA_blank'
'testB_blank'
(hangs here does not return)
que parece que se está llegando al final de tampón de HTE y en vez de volver Ninguno o '' se cuelga la espera de más de entrada.
¿Qué debo buscar para ver si la salida se ha completado? al final de la memoria intermedia? un carácter no imprimible?
---------------- ------------- editar
este happends también cuando corro xpcshell en lugar de ls, estoy suponiendo que estos programas interactivos tienen alguna forma de saber para mostrar el indicador, strangly la indicación, en este caso "js>" Nunca apears
Solución
Bueno, en realidad su salida no ha terminado. Debido a que dio lugar a /bin/sh
, la cáscara sigue funcionando después de la ultima "LS". No hay ningún indicador EOF, porque aún en marcha.
¿Por qué no sólo tiene que ejecutar /bin/ls
?
Se podría hacer algo como
pfd = subprocess.Popen(['ls'], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
out, err_output = pfd.communicate()
Esto también destaca subprocess.communicate
, que es una forma más segura de obtener una salida (Para salidas que caben en la memoria, de todos modos) de una sola ejecución del programa. Esto devolverá sólo cuando el programa ha terminado de ejecutarse.
Como alternativa, -could- leer linewise de la cáscara, pero podría estar buscando una secuencia de shell especial como la línea sh~#
que fácilmente podría aparecer en la salida del programa. Por lo tanto, ejecutar un intérprete es probablemente una mala idea por todas partes.
Editar Esto es lo que se refería, pero todavía no es realmente la mejor solución, ya que tiene un montón de advertencias:
while 1:
c = pfd.stdout.read(1)
if not c:
break
elif c == '\n': # print line when found
print repr(out)
out = ''
else:
out += c
if out.strip() == 'sh#':
break
Tenga en cuenta que esto va a romper si otras salidas de comando sh '#' al comienzo de la línea, y también si por alguna razón la salida es diferente de lo esperado, se entra en la misma situación de bloqueo como antes. Esto es por qué es una situación muy sub-óptimo para una concha.
Otros consejos
Para aplicaciones como una concha, la salida no termina hasta que termina la cáscara. O bien utilizar select.select()
para comprobar si tiene más salida a la espera de que, o terminar el proceso.