¿Desconectarse de una sesión SSH mata sus programas?

88

Por lo tanto, decir que se desconecta de una sesión SSH-después de iniciar rsynco cpo cualquier otro comando que puede ser de larga ejecución. ¿Ese comando sigue ejecutándose hasta que finalice después de que me desconecte o simplemente me matan?

Siempre me pregunté esto.

Fregas
fuente
Solo quiero agregar a lo que se ha dicho anteriormente que, si se encuentra en una situación en la que necesita poner un proceso en ejecución screen, intente reptyr .
un tipo triste el
Matará tus programas. Muy molesto si está actualizando la versión del sistema operativo de Ubuntu 16.04 a 17.10 a través de SSH
kurdtpage

Respuestas:

118

Editar para 2016:

Estas preguntas y respuestas son anteriores a la debacle de systemd v230 . A partir de systemd v230, el nuevo valor predeterminado es matar a todos los hijos de una sesión de inicio de sesión final, independientemente de las precauciones históricamente válidas que se tomaron para evitar esto. El comportamiento se puede cambiar mediante el establecimiento KillUserProcesses=noen /etc/systemd/logind.conf, o eludidas mediante los mecanismos de systemd específico para el inicio de un daemon en el espacio de usuario. Esos mecanismos están fuera del alcance de esta pregunta.

El texto a continuación describe cómo las cosas han funcionado tradicionalmente en el espacio de diseño de UNIX durante más tiempo del que Linux ha existido.


Los matarán, pero no necesariamente de inmediato. Depende de cuánto tiempo le tome al demonio SSH decidir que su conexión está desconectada. Lo que sigue es una explicación más larga que lo ayudará a comprender cómo funciona realmente.

Cuando inició sesión, el daemon SSH le asignó un pseudo-terminal y lo adjuntó al shell de inicio de sesión configurado de su usuario. Esto se llama terminal de control. Cada programa que inicie normalmente en ese punto, sin importar cuántas capas de capas profundas, finalmente rastreará su ascendencia hasta esa capa. Puedes observar esto con el pstreecomando.

Cuando el proceso del demonio SSH asociado con su conexión decide que su conexión está inactiva, envía una señal de bloqueo ( SIGHUP) al shell de inicio de sesión. Esto notifica al shell que desapareció y que debería comenzar a limpiarse después de sí mismo. Lo que sucede en este punto es específico del shell (busque "HUP" en su página de documentación), pero en su mayor parte comenzará a enviarse SIGHUPa trabajos en ejecución asociados antes de finalizar. Cada uno de esos procesos, a su vez, hará lo que sea que estén configurados para hacer al recibir esa señal. Por lo general, eso significa terminar. Si esos trabajos tienen trabajos propios, la señal a menudo también se transmitirá.

Los procesos que sobreviven a un bloqueo del terminal de control son aquellos que se desasociaron de tener un terminal (procesos de daemon que comenzaste dentro de él) o que se invocaron con un nohupcomando prefijado . (es decir, "no cuelgues en esto") Daemons interpreta la señal HUP de manera diferente; dado que no tienen un terminal de control y no reciben automáticamente una señal HUP, en cambio, se reutiliza como una solicitud manual del administrador para volver a cargar la configuración. Irónicamente, esto significa que la mayoría de los administradores no aprenden el uso "colgado" de esta señal para los no demonios hasta mucho, mucho más tarde. ¡Es por eso que estás leyendo esto!

Los multiplexores de terminales son una forma común de mantener intacto su entorno de shell entre desconexiones. Le permiten desconectarse de sus procesos de shell de manera que pueda volver a conectarlos más tarde, independientemente de si esa desconexión fue accidental o deliberada. tmuxy screenson los más populares; la sintaxis para usarlos está más allá del alcance de su pregunta, pero vale la pena analizarlos.


Se me solicitó que explicara cuánto tiempo le lleva al demonio SSH decidir que su conexión está desconectada. Este es un comportamiento que es específico de cada implementación de un demonio SSH, pero puede contar con que todos terminen cuando cualquier lado restablezca la conexión TCP. Esto sucederá rápidamente si el servidor intenta escribir en el socket y no se reconocen los paquetes TCP, o lentamente si nada intenta escribir en el PTY.

En este contexto particular, los factores más probables para desencadenar una escritura son:

  • Un proceso (generalmente el que está en primer plano) que intenta escribir en el PTY en el lado del servidor. (servidor-> cliente)
  • El usuario que intenta escribir en el PTY en el lado del cliente. (cliente-> servidor)
  • Keepalives de cualquier tipo. Por lo general, estos no están habilitados de forma predeterminada, ya sea por el cliente o el servidor, y generalmente hay dos tipos: nivel de aplicación y basado en TCP (es decir SO_KEEPALIVE). Keepalives equivale a que el servidor o el cliente envían paquetes con poca frecuencia al otro lado, incluso cuando nada tendría una razón para escribir en el socket. Si bien esto normalmente tiene como objetivo eludir los cortafuegos que desconectan las conexiones demasiado rápido, tiene el efecto secundario adicional de hacer que el remitente se dé cuenta cuando el otro lado no responde mucho más rápido.

Las reglas habituales para las sesiones TCP se aplican aquí: si hay una interrupción en la conectividad entre el cliente y el servidor, pero ninguna de las partes intenta enviar un paquete durante el problema, la conexión sobrevivirá siempre que ambas partes respondan después y reciban el TCP esperado números de secuencia

Si un lado ha decidido que el socket está muerto, los efectos suelen ser inmediatos: el proceso sshd se enviará HUPy finalizará automáticamente (como se describió anteriormente), o el cliente notificará al usuario el problema detectado. Vale la pena señalar que solo porque un lado piense que el otro está muerto no significa que el otro haya sido notificado de esto. El lado huérfano de la conexión generalmente permanecerá abierto hasta que intente escribir en él y se agote el tiempo de espera, o reciba un restablecimiento de TCP desde el otro lado. (si la conectividad estaba disponible en ese momento) La limpieza descrita en esta respuesta solo ocurre una vez que el servidor se ha dado cuenta.

Andrew B
fuente
3
También agregaría el comando 'dtach' a esa lista: es algo opuesto a screen / tmux, ya que le permite conectar múltiples terminales a una sola sesión, y también es ideal para prolongar una sesión, aunque no lo hace proporcionar cualquier medio para reproducir la historia reciente.
esponjoso
dtachurl está aquí: dtach.sourceforge.net
slm
2
Excelente explicación. Ya me siento más linuxey!
Fregas
3
Además, si bien no es técnicamente parte de su respuesta, aquí hay un interesante dato curioso: puede usarlo kill -HUPcomo root para obligar a la terminal de alguien a colgar. No deberías hacer esto sin una buena razón. Obtengo la mayor parte de mi kilometraje cuando los usuarios dejan shells en ejecución durante el mantenimiento y necesito desmontar un sistema de archivos que su shell se mantiene abierto. Si el usuario está conectado pero inactivo, envíe la señal a su proceso sshd. De lo contrario, si se ejecuta dentro de un multiplexor de terminal, envíelo al shell que desea detener. ¡Solo cuelga el caparazón para que no trabajes!
Andrew B
@ AndrewB, ¿podría explicar cómo "el proceso del demonio SSH ... decide que su conexión está inactiva"? ¿Y cómo puedo saber si el demonio SSH piensa / sabe que la (qué) conexión está muerta o no?
Xiao Peng - ZenUML.com
22

Como otros han mencionado, una vez que se desconecta de ssh, todo lo que se ejecuta dentro de él desaparece.

Como @Michael Hampton y otros han mencionado, puede usar herramientas como tmuxo screenpara desconectarse / volver a conectarse a terminales sin perder su contenido (es decir, procesos secundarios).

Además, puede poner un proceso en segundo plano con un ampersand &y luego usar el comando disownpara desasociarlos con el shell actual.

# start a command
% sleep 5000 &
[1] 3820

# check it
% jobs
[1]+  Running                 sleep 5000 &

# disown everything
% disown -a

# check it again (gone from shell)
% jobs
%

# but it's still running on the system
% ps -eaf|grep "[s]leep"
saml      3820 23791  0 00:16 pts/1    00:00:00 sleep 5000
%
slm
fuente
¿Es posible volver a conectar una sesión de terminal a un disownproceso ed?
Nombre falso el
44
Si. Vea esta pregunta U&L para más detalles: unix.stackexchange.com/questions/4034/…
slm
13

No, cualquier programa que todavía esté conectado a la terminal y que no se coloque en el fondo con algo así nohup, sería eliminado.

Esta es la razón por la cual existen soluciones de terminal virtual como tmuxlas anteriores screenque crean sesiones que continúan ejecutándose incluso si está desconectado, y a las que puede volver a conectar más tarde.

Michael Hampton
fuente