¿Por qué mi proceso sigue ejecutándose después de cerrar sesión?

¿Por qué mi proceso sigue ejecutándose después de cerrar sesión?

Después de iniciar sesión ssh, escribo este comando en bash:

sleep 50000000000000 &

Luego soy kill -9el sleepproceso padre del proceso (es decir, bash). Luego, la ventana de la terminal se desconecta simultáneamente.

Cuando vuelvo a iniciar sesión, encuentro que el sleepproceso aún está activo.

Pregunta: ¿Por qué el sleepproceso puede sobrevivir cuando cierro sesión y el terminal está cerrado? En mi opinión, todo, excepto los demonios y nohuplos programas, se eliminará durante el cierre de sesión. Si sleeppuedo sobrevivir de esta manera, ¿significa que puedo usar este método en lugar del nohupcomando?

Respuesta1

Dr.:

¿Por qué el sleepproceso puede sobrevivir cuando cierro sesión y se cierra la terminal? En mi opinión, todo, excepto los demonios y nohuplos programas, se eliminará durante el cierre de sesión. Si sleeppuedo sobrevivir de esta manera, ¿significa que puedo usar este método en lugar del nohupcomando?

A menos que la bashinstancia generada sshtenga la huponexitopción configurada, ningún proceso finalizará de ninguna manera al salir/cerrar sesión, y cuando la huponexitopción está configurada, usar kill -9en el shell no es una buena alternativa a usarlo nohupen los procesos secundarios del shell; nohupen los procesos secundarios del shell aún los protegerá de SIGHUP que no provienen del shell, e incluso cuando eso no sea importante, nohupes preferible porque permite que el shell finalice correctamente.


Hay bashuna opción llamada huponexit, que si está configurada hará que bashSIGHUP sea sus hijos al salir/cerrar sesión;

En interactivosin iniciar sesión bashEn instancias, como en una bashinstancia generada por gnome-terminal, esta opción se ignora; ya sea que huponexitesté configurado o no, bashlos hijos de ' nunca serán avisados ​​al bashsalir;

En interactivoacceso bashEn instancias, como en una bashinstancia generada por ssh, esta opción no se ignora (sin embargo, no está configurada de forma predeterminada); si huponexitestá configurado, bashlos hijos de ' recibirán un SIGHUP bashal salir/cerrar sesión; si huponexitno está configurado, bashlos hijos de ' no serán SEGUIDOS al bashsalir/cerrar sesión;

Entonces, en general, salir/cerrar sesión de una bashinstancia de inicio de sesión interactiva, a menos que la huponexitopción esté configurada, no hará que el shell SIGHUP sea su hijo, y salir/cerrar sesión de una bashinstancia interactiva sin inicio de sesión no hará que el shell SIGHUP sea su hijo. a pesar de todo;

Sin embargo, esto es irrelevante en este caso: el uso kill -9 sleepsobrevivirá independientemente, porque matar su proceso padre ( bash) no dejará ninguna posibilidad para que este último lo haga.cualquier cosaal primero (es decir, por ejemplo, si la bashinstancia actual era una bashinstancia de inicio de sesión y la huponexitopción estaba configurada, SIGHUP).

Además de esto, a diferencia de otras señales (como una señal SIGHUP enviada a bash), una señal SIGKILL nunca se propaga a los procesos secundarios de un proceso, por lo tanto, sleepni siquiera se elimina;

nohupinicia un proceso inmune a las señales SIGHUP, que es algo diferente; evitará que el proceso se cuelgue al recibir una señal SIGHUP, que en este caso podría ser recibida por la bashinstancia de inicio de sesión interactiva en caso de que huponexitse haya configurado la opción y se haya cerrado el shell; por lo tanto, técnicamente usar nohuppara iniciar un proceso en una bashinstancia de inicio de sesión interactiva con la huponexitopción no configurada evitará que el proceso se cuelgue al recibir una señal SIGHUP, pero salir/cerrar sesión del Shell no lo hará SIGHUP de todos modos;

Sin embargo, en general, cuando nohupes necesario evitar que las señales SIGHUP provengan del shell principal, no hay razón para preferir el kill -9método principal al nohupmétodo secundario; en cambio, debería ser lo contrario.

Matar al padre usando el kill -9método no deja una posibilidad para que el padre salga con gracia, mientras que iniciar al niño usando el nohupmétodo permite que el padre sea terminado por otras señales, como SIGHUP (para hacer un ejemplo que tenga sentido en el contexto). de un niño comenzó a usar nohup), que le permiten salir con gracia.

Respuesta2

bashpor defectono envía la señal HUP a los procesos secundarios al salir. Más en detalle (gracias @kos), nunca lo hace porshells sin inicio de sesión.

Puedes configurar bash para que lo haga porshells de inicio de sesiónsi configura la opción huponexit. En una terminal, haga:

[romano:~] % bash -l

(esto inicia un nuevo shell de "inicio de sesión")

romano@pern:~$ shopt -s huponexit
romano@pern:~$ sleep 1234 &
[1] 32202
romano@pern:~$ exit
logout

Ahora verifique el sleepproceso:

[romano:~] % ps augx | grep sleep
romano   32231  0.0  0.0  16000  2408 pts/11   S+   15:23   0:00 grep sleep

...no funcionando: recibió la señal HUP y salió según lo solicitado.

Respuesta3

¿ sleepPuedo sobrevivir de esta manera, si eso significa que puedo usar este método en lugar del nohupcomando?

kill -9Realmente no es el camino que uno debería seguir. Es como disparar con una pistola al televisor para apagarlo. Aparte del componente cómico, no hay ninguna ventaja. Los procesos no pueden detectar ni ignorar SIGKILL. Si no le da al proceso la oportunidad de terminar lo que está haciendo y limpiar, es posible que deje archivos corruptos (u otro estado) y no podrá comenzar de nuevo. kill -9es la última esperanza, cuando nada más funciona.


Por qué el proceso de suspensión puede sobrevivir cuando cierro sesión y el terminal está cerrado. En mi opinión, todo, excepto el demonio y el programa nohup, se eliminará al cerrar sesión.

Lo que en tu caso sucede:

El proceso principal de sleepes el shell que se está ejecutando actualmente bash. Cuando realiza kill -9ese bash, el proceso bash no tiene la posibilidad de enviar un SIGHUPa ninguno de sus procesos secundarios, porque SIGKILL(que es enviado por kill -9) no es capturable por el proceso. El proceso de sueño continúa ejecutándose. Dormir ahora se convirtió en unproceso huérfano.

El proceso init (PID 1) realiza un mecanismo llamado reparenting. Eso significa que el proceso init ahora se convierte en el padre de ese proceso huérfano. init es una excepción, los procesos pueden convertirse en sus hijos ya que recopila procesos que perdieron su proceso padre original. Por cierto: un demonio (como sshd) hace eso cuando "va en segundo plano".

Si eso no sucediera, el proceso huérfano se convertiría más tarde (cuando finalice) en un proceso zombie. Esto es lo que sucede cuando waitpid()no se llama (una responsabilidad del proceso principal que no se puede cumplir cuando ese proceso fue eliminado). init llama waitpid()en un intervalo específico para evitar niños zombies.

Respuesta4

El uso &hará que el programa se ejecute en segundo plano. Para ver el programa en segundo plano bg, utilice el comando y, para que vuelva a ejecutarse en primer plano, ejecute fg.

Sí, hay muchas formas de mantener el programa ejecutándose incluso cuando se cierra la terminal principal.

información relacionada