¿Los programas que se ejecutan desde una sesión ssh dependen de la conexión?

29

¿Un programa que se ejecuta desde una sesión ssh depende de la conexión con el cliente? Por ejemplo, cuando la conexión es realmente lenta. Entonces, ¿espera activamente hasta que las cosas se impriman en la pantalla?

Y si depende de la conexión, ¿también sucede con la pantalla o byobu, por ejemplo? Dado que con estos, los programas se siguen ejecutando incluso después de desconectarse del host.


Nota: Solo encontré estas preguntas relacionadas:

un oro
fuente
1
Tenga en cuenta que si su conexión se pierde, el programa continuará ejecutándose hasta que la sesión finalice (a menos que esté atascado en una operación de impresión), pero si su sesión finaliza, el programa finalizará con gracia.
Sebb

Respuestas:

26

La salida de los programas se almacena en búfer, por lo que si la conexión es lenta, el programa se detendrá si el búfer se llena.

Si lo usa screen, también tiene un búfer que se usa para intentar mostrar en una sesión conectada. Pero un programa conectado en la sesión de pantalla no se detendrá si screenno puede actualizar el terminal remoto lo suficientemente rápido. Al igual que cuando se pierde una conexión, el programa continúa llenando el screensbúfer hasta que se desborda (eliminando la información más antigua). Lo que ve venir (y puede desplazarse hacia atrás) depende de lo que esté (todavía) en ese búfer. screenefectivamente desalienta tu programa desde tu terminal (y tu lenta conexión SSH).

Anthon
fuente
9

Una conexión SSH puede morir prematuramente si la conexión TCP subyacente recibe un paquete con el indicador RST . Eso podría suceder si un lado envía un paquete (que podría ser una sonda de mantenimiento de SSH periódica) pero no recibe un acuse de recibo de TCP en un período de tiempo razonable, o si un enrutador decide que la conexión ha estado inactiva durante demasiado tiempo, o si un ISP es solo ser malvado.

En el modelo de terminal Unix, cuando se cae la conexión de terminal, el controlador de terminal envía una señal HUP al shell, cuya terminación también hace que se envíe un SIGHUP a los procesos que se ejecutan en el shell.

De las Preguntas frecuentes del Programador de Unix , elemento 1.15:

SIGHUPes una señal que significa, por convención, "la línea terminal se colgó". No tiene nada que ver con los procesos primarios, y generalmente es generado por el controlador tty (y entregado al grupo de procesos en primer plano).

Sin embargo, como parte del sistema de gestión de la sesión, hay exactamente dos casos en los que SIGHUPse envía al fallecer un proceso:

  • Cuando el proceso que muere es el líder de sesión de una sesión que está conectada a un dispositivo terminal, SIGHUPse envía a todos los procesos en el grupo de procesos en primer plano de ese dispositivo terminal.

  • Cuando la muerte de un proceso hace que un grupo de procesos quede huérfano, y uno o más procesos en el grupo huérfano se detienen , SIGHUPy luego SIGCONTse envían a todos los miembros del grupo huérfano. (Un grupo de procesos huérfanos es aquel en el que ningún proceso en el grupo tiene un padre que es parte de la misma sesión, pero no el mismo grupo de procesos).

El controlador de señal predeterminado para SIGHUP es terminar el proceso:

Signal     Value     Action   Comment
----------------------------------------------------------------------
SIGHUP        1       Term    Hangup detected on controlling terminal
                              or death of controlling process

Sin embargo, es posible evitar la finalización del proceso.

  • Puede insertar un controlador de señal que ignore SIGHUP. Para hacerlo como usuario, envuelva el comando nohup. Por ejemplo:

    nohup make all &
    
  • Puede decirle al shell que disocie un proceso hijo de él. Por ejemplo, Bash tiene un disowncomando incorporado:

    make all
    

    CtrlZ

    bg
    disown %1
    

    Entonces, el SIGHUP no se propagará al niño (que ya no es un niño).

  • Algunos programas, especialmente los demonios , utilizarán los mecanismos anteriores automáticamente: un programa puede instalar un controlador SIGHUP alternativo (usando sigaction(2)), o podría optar por unirse a una nueva sesión ( setsid(2)).
  • Puede ejecutar screeno tmux, lo que asigna un pseudo-TTY para ejecutar una sesión con un shell que no recibe el SIGHUP cuando se corta la conexión SSH. El SIGHUP no se retransmite desde la sesión SSH a la sesión screen / tmux.

Por cierto, una forma alternativa de lidiar con conexiones SSH poco confiables es usar el protocolo Mosh . Mosh se ejecuta sobre UDP, por lo que no hay conexión TCP que corra el riesgo de restablecerse.

200_success
fuente
Lectura adicional: Diferencia entre nohup, disown y & .
200_success
1

Sí, un programa que se ejecuta sobre SSH dependerá de que su salida vaya a algún lado. Si la conexión es lenta, la salida debe estar almacenada en algún lugar y los almacenamientos intermedios no pueden ser infinitos, por lo que el programa debe bloquearse si están llenos.

Tenga en cuenta que la salida no necesariamente va a un terminal: considere ejecutar algo como

ssh user@somewhere "cat file.txt" > file.txt

En efecto, esto copiará el archivo. Para que esto funcione, la tasa de salida de cat debe coincidir con la de la conexión: debería ser obvio que perder partes de la salida del medio sería inaceptable.

La pantalla cambiará la situación, ya que actúa como un terminal y guardará lo que debe mostrarse "en la ventana del terminal" (más desplazamiento hacia atrás). No necesita recordar todo lo que genera su programa, solo las partes que se ajustarán a la "ventana" y al desplazamiento hacia atrás. Por defecto, la pantalla esperará una conexión lenta (bloqueando el programa), pero se puede configurar para detectar una conexión atascada al configurar "no bloqueado".

Desde la página del manual:

sin bloqueo [on | off | numsecs]

Indique a la pantalla cómo manejar las interfaces de usuario (pantallas) que dejan de aceptar la salida. Esto puede suceder si un usuario presiona ^ S o se corta una conexión TCP / módem pero no se recibe ningún bloqueo. Si la función no bloqueo está desactivada (este es el valor predeterminado), la pantalla espera hasta que la pantalla se reinicie para aceptar la salida. Si el bloqueo no está activado, la pantalla espera hasta que se alcanza el tiempo de espera (activado se trata como 1s). Si la pantalla aún no recibe caracteres, la pantalla la considerará "bloqueada" y dejará de enviarle caracteres. Si en algún momento se reinicia para aceptar caracteres, la pantalla desbloqueará la pantalla y volverá a mostrar el contenido actualizado de la ventana.

Una desconexión es diferente a una conexión lenta. Plain SSH no se puede recuperar automáticamente, por lo que su programa recibirá un SIGHUP. Por otro lado, la pantalla detectará una desconexión, se desconectará y volverá a la memoria intermedia local hasta que se vuelva a conectar la pantalla. Esto no bloqueará el programa en ejecución.

(La configuración nonblock 1en su .screenrces importante si ejecuta algo como irssi que producirá continuamente salida pero que aún debe hablar con la red al mismo tiempo. El bloqueo conduciría a desconectarse del IRC, lo cual es extremadamente molesto ...)

ilkkachu
fuente