Solución 1:
Editar para 2016:
Esta sesión de preguntas y respuestas es anterior a la debacle de systemd v230. A partir de systemd v230, el nuevo valor predeterminado es matar a todos los elementos secundarios de una sesión de inicio de sesión finalizada, independientemente de las precauciones históricamente válidas que se hayan tomado para evitarlo. El comportamiento se puede cambiar configurando KillUserProcesses=no
en /etc/systemd/logind.conf
, o eludido utilizando los mecanismos específicos de systemd para iniciar un demonio en el espacio de usuario. Esos mecanismos están fuera del alcance de esta pregunta.
El texto a continuación describe cómo han funcionado tradicionalmente las cosas en el espacio de diseño de UNIX desde que existe Linux.
Los matarán, pero no necesariamente de inmediato. Depende de cuánto tiempo tarde el demonio SSH en decidir que su conexión está muerta. Lo que sigue es una explicación más larga que lo ayudará a comprender cómo funciona realmente.
Cuando inició sesión, el demonio SSH le asignó un pseudo terminal y lo adjuntó al shell de inicio de sesión configurado de su usuario. Esto se llama el terminal de control. Cada programa que inicie normalmente en ese punto, sin importar cuántas capas de caparazones profundicen, en última instancia rastreará su ascendencia hasta ese caparazón. Puedes observar esto con el pstree
comando.
Cuando el proceso del demonio SSH asociado con su conexión decide que su conexión está inactiva, envía una señal de colgado (SIGHUP
) al shell de inicio de sesión. Esto notifica al caparazón que has desaparecido y que debe comenzar a limpiarse. 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 enviar SIGHUP
para ejecutar trabajos asociados con él antes de terminar. Cada uno de esos procesos, a su vez, hará lo que esté configurado para hacer al recibir esa señal. Por lo general, eso significa terminar. Si esos trabajos tienen sus propios trabajos, la señal a menudo también se transmitirá.
Los procesos que sobreviven a un bloqueo del terminal de control son los que se desvincularon de tener un terminal (procesos daemon que inició dentro de él) o los que se invocaron con un prefijo nohup
dominio. (es decir, "no cuelgues esto") Los demonios interpretan la señal HUP de manera diferente; dado que no tienen una terminal de control y no reciben automáticamente una señal HUP, en su lugar se reutiliza como una solicitud manual del administrador para recargar la configuración. Irónicamente, esto significa que la mayoría de los administradores no aprenden el uso de "colgar" de esta señal para los no demonios hasta mucho, mucho más tarde. ¡Por eso 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. tmux
y screen
son los más populares; la sintaxis para usarlos está más allá del alcance de su pregunta, pero vale la pena investigarlos.
Se me solicitó que explicara cuánto tiempo le toma al demonio SSH decidir que su conexión está muerta. Este es un comportamiento que es específico de cada implementación de un demonio SSH, pero puede contar con que todos terminarán cuando cualquiera de los dos restablezca la conexión TCP. Esto sucederá rápidamente si el servidor intenta escribir en el socket y los paquetes TCP no se reconocen, o lentamente si nada intenta escribir en el PTY.
En este contexto particular, los factores con más probabilidades de desencadenar una escritura son:
- Un proceso (normalmente el que está en primer plano) que intenta escribir en el PTY del lado del servidor. (servidor->cliente)
- El usuario que intenta escribir en el PTY del lado del cliente. (cliente->servidor)
- Keepalives de cualquier tipo. Por lo general, 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 generalmente tiene la intención de eludir los firewalls que agotan el tiempo de espera de 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.
Aquí se aplican las reglas habituales para las sesiones TCP:si hay una interrupción en la conectividad entre el cliente y el servidor, pero ninguno de los lados intenta enviar un paquete durante el problema, la conexión sobrevivirá siempre que ambos lados 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 enviará HUP
y terminar automáticamente (como se describió anteriormente), o el cliente notificará al usuario sobre el problema detectado. Vale la pena señalar que el hecho de que 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 del 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.
Solución 2:
Como han mencionado otros, 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 tmux
o screen
para desconectar/reconectar terminales sin perder su contenido (es decir, procesos secundarios).
Además, puede poner un proceso en segundo plano usando un ampersand &
y luego usa el comando disown
para 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
%
Solución 3:
No, cualquier programa aún conectado a la terminal y no colocado en segundo plano con algo como nohup
, sería asesinado.
Es por eso que existen soluciones de terminales virtuales como tmux
y el antiguo screen
que crean sesiones que continúan ejecutándose incluso si está desconectado y a las que puede volver a conectarse más tarde.