¿Por qué SSH -t no espera los procesos en segundo plano?

13

¿Por qué ssh -tno espera a que finalicen los trabajos en segundo plano?

Ejemplo:

ssh user@example 'sleep 2 &'

Esto funciona como se esperaba, ya que ssh regresa después de 2 segundos, mientras que

ssh user@example -t 'sleep 2 &'

no espera a sleepque termine y regresa de inmediato.

¿Alguien puede explicar la razón detrás de esto? ¿Hay alguna manera de ssh -tesperar a que finalicen todos los procesos en segundo plano antes de regresar?

Mi caso de uso es que comienzo una secuencia de comandos ssh -t, y esta secuencia de comandos inicia varios trabajos en segundo plano que deberían mantenerse activos después de que finalice la secuencia de comandos principal. Con ssh -testo no es posible hasta ahora.

Philipp Murry
fuente

Respuestas:

22

Sin -t, sshdobtiene el stdout del shell remoto (y a los niños les gusta sleep) y stderr a través de dos canales (y también envía la entrada del cliente a través de otro canal).

sshd espera el proceso en el que ha iniciado el shell de inicio de sesión del usuario, pero también, después de que ese proceso ha terminado, espera eof en la tubería stdout (no la tubería stderr en el caso de openssh al menos).

Y eof ocurre cuando no hay un descriptor de archivo por ningún proceso abierto en el extremo de escritura de la tubería, lo que generalmente ocurre cuando todos los procesos que no tenían su stdout redirigido a otra cosa se han ido.

Cuando lo usas -t, sshdno usa tuberías. En cambio, toda la interacción (stdin, stdout, stderr) con el shell remoto y sus hijos se realiza utilizando un par pseudo-terminal.

Con un par de pseudo-terminales, para sshdinteractuar con el lado maestro, no existe un manejo de eof similar ni ninguna forma de saber si todavía hay procesos con fds abiertos al lado esclavo del pseudo-terminal, por lo que solo espera la terminación de el proceso en el que ejecutó el shell de inicio de sesión del usuario remoto y luego sale.

En esa salida, el lado maestro del par pty se cierra, lo que significa que se destruye el pty, por lo que los procesos controlados por el esclavo recibirán un SIGHUP (que por defecto los terminaría).

Stéphane Chazelas
fuente
1
gracias por la respuesta completa! Otra cosa que me gustaría saber: ¿todos los procesos en segundo plano finalizan una vez que sale el pseudo terminal? el script que estoy iniciando inicia un servicio, que funciona bien con ssh. pero cuando se usa ssh -t, el servicio no se inicia. parece que el servicio se cierra una vez que ssh regresa.
Philipp Murry
En realidad, hay una manera para que el lado maestro de un pseudo-terminal sepa cuándo se han cerrado todos los descriptores de archivos esclavos. Es el mismo mecanismo desencadenado por un terminal real cuando todos los descriptores de archivo se han cerrado, de hecho.
JdeBP
@JdeBP, ¿te gustaría expandirte? No estoy seguro de lo que quieres decir. Los emuladores de terminal AFAICT (xterm y gnome-terminal al menos) no se preocupan por los procesos que aún tienen fds abiertos al esclavo cuando el proceso en el que ejecutaron el shell muere
Stéphane Chazelas
@PhilippMurry Puede usar nohuppara mantener una secuencia de comandos ejecutándose así. (También puede considerar iniciar los trabajos de larga ejecución dentro de tmuxlo que puede supervisar su progreso de forma interactiva, sino un archivo de registro funciona bien.)
jpaugh
5

Uso wait:

ssh user@example -t 'sleep 2 & wait'
Ipor Sircer
fuente