¿Qué determina exactamente si se mata un trabajo en segundo plano cuando se sale o se mata el shell?

12

Esta cuestión ha llegado bastante un montón ( realmente mucho ), pero estoy encontrando las respuestas sean generalmente incompleta. La pregunta general es "¿Por qué mi trabajo es / no es asesinado cuando salgo / mato ssh?", Y esto es lo que he encontrado. La primera pregunta es: ¿Qué tan general es la siguiente información? Lo siguiente parece ser cierto para el Linux Debian moderno, pero me faltan algunos bits; ¿Y qué necesitan saber los demás?

  1. Todos los procesos secundarios, en segundo plano o no, de un shell abierto sobre una conexión ssh se eliminan con SIGHUP cuando la conexión ssh se cierra solo sihuponexit se establece la opción: ejecutar shopt huponexitpara ver si esto es cierto.

  2. Si huponexites cierto, puede usar nohupo disowndisociar el proceso del shell para que no se mate cuando salga. O, corre las cosas con screen.

  3. Si huponexites falso, que es el valor predeterminado en al menos algunos Linux en estos días, los trabajos en segundo plano no se eliminarán en el cierre de sesión normal.

  4. Pero incluso si huponexites falso, entonces si la conexión ssh se corta o se cae (diferente a la desconexión normal), los procesos en segundo plano seguirán siendo eliminados. Esto se puede evitar con disowno nohupcomo en (2).

  5. Hay alguna distinción entre (a) procesos cuyo proceso padre es el terminal y (b) procesos que tienen stdin, stdout o stderr conectados al terminal . No sé qué sucede con los procesos que son (a) y no (b), o viceversa.

Pregunta final: ¿Cómo puedo evitar el comportamiento (3)? En otras palabras, de forma predeterminada en Debian, los procesos en segundo plano se ejecutan alegremente por sí mismos después de cerrar la sesión, pero no después de que se corte la conexión ssh. Me gustaría que ocurriera lo mismo con los procesos independientemente de si la conexión se cerró normalmente o se cortó. ¿O es una mala idea?

Editar: Otra forma importante de mantener los trabajos de ser asesinado, que funciona (?) En ambos casos es ejecutarlos a través de la pantalla . Pero, la pregunta es más acerca de comprender cuándo se matan las cosas y cuándo no: a veces las personas quieren que los trabajos se maten al cerrar sesión, por ejemplo.

Más hilos: - Aclaración de señales (sighup), trabajos y el terminal de control - /server/117152/do-background-processes-get-a-sighup-when-logging-off - Continuar SSH Tarea en segundo plano / trabajos al cerrar SSH : ¿continuará ejecutándose un trabajo en segundo plano después de cerrar una sesión SSH? - Evite que un proceso en segundo plano que ya se está ejecutando se detenga después de cerrar el cliente SSH - ¿Cómo puedo iniciar un proceso a través de SSH para que continúe ejecutándose después de desconectarme? - No se puede mantener el trabajo remoto ejecutándose en OS X - Cerrar la conexión SSH

petrelharp
fuente

Respuestas:

1

Un proceso no se "mata con SIGHUP", al menos, no en el sentido estricto de la palabra. En cambio, cuando se corta la conexión, el proceso de control del terminal (en este caso, Bash) recibe una señal de colgar *, que generalmente se abrevia como "señal HUP", o simplemente SIGHUP.

Ahora, cuando un proceso recibe una señal, puede manejarlo de la forma que desee **. El valor predeterminado para la mayoría de las señales (incluida HUP) es salir inmediatamente. Sin embargo, el programa es libre de ignorar la señal, o incluso de ejecutar algún tipo de función de controlador de señal.

Bash elige la última opción. Su controlador de señal HUP verifica si la opción "huponexit" es verdadera y, de ser así, envía SIGHUP a cada uno de sus procesos secundarios. Solo una vez que termina con eso, Bash sale.

Del mismo modo, cada proceso secundario es libre de hacer lo que quiera cuando recibe la señal: dejarlo configurado por defecto (es decir, morir de inmediato), ignorarlo o ejecutar un controlador de señal.

Nohup solo cambia la acción predeterminada para el proceso secundario a "ignorar". Sin embargo, una vez que el proceso secundario se está ejecutando, es gratis cambiar su propia respuesta a la señal.

Creo que esta es la razón por la que algunos programas mueren aunque los ejecutaste con nohup:

  1. Nohup establece la acción predeterminada para "ignorar".
  2. El programa necesita hacer algún tipo de limpieza cuando sale, por lo que instala un controlador SIGHUP, sobrescribiendo incidentalmente el indicador "ignorar".
  3. Cuando llega el SIGHUP, el controlador se ejecuta, limpia los archivos de datos del programa (o lo que sea necesario hacer) y sale del programa.
  4. El usuario no conoce ni se preocupa por el controlador o la limpieza, y solo ve que el programa salió a pesar de nohup.

Aquí es donde entra en juego "disown". Un proceso que Bash ha rechazado nunca envía la señal HUP, independientemente de la opción huponexit. Entonces, incluso si el programa configura su propio controlador de señal, la señal nunca se envía realmente, por lo que el controlador nunca se ejecuta. Tenga en cuenta, sin embargo, que si el programa intenta mostrar algo de texto a un usuario que ha cerrado la sesión, causará un error de E / S, lo que podría hacer que el programa se cierre de todos modos.

* Y, sí, antes de preguntar, la terminología de "colgar" queda de los días del sistema principal de acceso telefónico de UNIX.

** La mayoría de las señales, de todos modos. SIGKILL, por ejemplo, siempre hace que el programa finalice inmediatamente, punto.

Paraguas oculto
fuente
2

Los puntos 1-4 son correctos. No sé nada sobre el punto 5. En cuanto a su punto final, una buena aplicación, pantalla , le permitirá dejar que todos los procesos se ejecuten a su fin natural, independientemente de cómo termine su conexión. La pantalla está en los repositorios.

La descripción del hombre de la pantalla no es fácil de leer, pero, entre otras cosas, establece:

Cuando se llama a screen, crea una sola ventana con un shell (o el comando especificado) y luego se aparta para que pueda usar el programa como lo haría normalmente. Luego, en cualquier momento, puede crear ventanas nuevas (pantalla completa) con otros programas (incluyendo más shells), eliminar ventanas existentes, ver una lista de ventanas, activar y desactivar el registro de salida, copiar y pegar texto entre ventanas, ver el historial de desplazamiento hacia atrás, alternar entre ventanas de la manera que desee, etc. Todas las ventanas ejecutan sus programas completamente independientes entre sí. Los programas continúan ejecutándose cuando su ventana no está visible actualmente e incluso cuando toda la sesión de pantalla está separada del terminal del usuario. Cuando un programa termina, la pantalla (por defecto) mata la ventana que lo contenía. Si esta ventana estaba en primer plano, la pantalla cambia a la ventana anterior; si no queda ninguno, la pantalla sale.

He resaltado la parte más importante: puede separar la ventana con el comando Ctrl + a + d, y luego puede cerrar / cerrar sesión, y la ventana ahora separada continuará viva, con los programas dentro aún ejecutándose. Cuando se conecta de nuevo, por ejemplo, al iniciar una nueva sesión ssh, el comando screen -r reanudará la sesión de pantalla que se había desconectado anteriormente, con toda la salida al error estándar / salida claramente visible.

MariusMatutiae
fuente