Este artículo demuestra el uso de la herramienta nohup para lanzar procesos inmunes a las señales de hangup (SIGHUP) en Linux. Esto sirve para mantener procesos en ejecución a pesar de que la terminal que lo controle se cierre (termine su ejecución).



En los sistemas operativos POSIX (particularmente GNU/Linux), la herramienta nohup permite lanzar un proceso ignorando las señales de hangup posteriores.

La señal de hangup, "colgar" en español, proviene del término que se utilizaba con los primeros teléfonos "de tubo" al momento de terminar una llamada. "Colgar" efectivamente significaba colgar el tubo (pieza de plástico o baquelita) que contenía el micrófono y auricular, uno en cada extremo. Vaya si seré viejo, soy de la época que había que "discar" en lugar de "marcar" los números al momento de comenzar una llamada. De niño tenía un trauma con el disco (ya de peque manejaba altos niveles de ansiedad). Pensaba que si tenía que llamar al 101 para pedir ayuda a la policía o bomberos, el tiempo en que tenía que esperar al disco en volver después de discar el 0, para poder discar el último 1, era tan grande que en ese lapso el asesino ya me apuñalaba o la casa se incendiaba toda. Por suerte después vinieron los teléfonos con teclado digital y se me pasó.

En los sistemas POSIX, la señal SIGHUP corresponde con la señal de hangup enviada a un proceso cuando se cierra (termina o finaliza su ejecución) la terminal que lo controla. Esta señal fue diseñada originalmente para notificar a un proceso la terminación de una comunicación a través de un puerto serie (o caída de la línea).

Por ende, cuando termina el proceso que corresponde con una terminal, se envía la señal de hangup a todos los procesos hijos para que finalicen a su vez su ejecución.

La herramienta nohup permite lanzar un proceso que ignore cualquier señal de SIGHUP que se le envíe. Pero además, redirecciona la salida estándar a un archivo (~/nohup.out) y la entrada estándar a un archivo ilegible (/dev/null). Sólo redirige la salida de errores a la salida estándar si se trata de una terminal.

Esta es otra herramienta parte del paquete coreutils.

Para entender el funcionamiento, conviene analizar directamente un ejemplo: lanzar un proceso ping en segundo plano (utilizando &).

Primero veamos qué ocurre con la salida y entrada estándar del proceso:

Al lanzar el proceso en segundo plano se libera el uso de la terminal, sin embargo toda su salida se redirige a la salida estándar (lo cual es muy molesto).

Se observa que el proceso tiene PID igual a 6657 y su padre padre tiene PID 3239 (el cual corresponde a la terminal de la sesión actual).

Luego, iniciando sesión como root para examinar la estructura del proceso dentro de /proc (interfase a las estructuras de datos del kernel Linux), se comprueba que la salida estándar (descriptor de archivo número 1) del proceso ping corresponde con la TTY actual.

Finalmente, si se envía la señal de hangup (kill -1) al proceso ping, este finaliza.

Ahora se lanza el mismo proceso pero con nohup:

La salida estándar es reenviada directamente al archivo nohup.out.

Al examinar el /proc se comprueba que la salida estándar está conectada directamente con dicho archivo. A su vez, la entrada estándar (descriptor de archivo número 0) está conectada con /dev/null (el dispositivo nulo).

Si se intenta enviar una o más señales de hangup al proceso, este las ignora. Sólo es posible "matarlo", finalizar la ejecución del proceso enviando la señal kill (kill -9) o la señal de terminación (kill -15).

Finalmente se corrobora que el archivo ~/nohup.out efectivamente contiene la salida del comando ping.

De esta forma se comprueba que el proceso lanzado con nohup ignora las señales de hangup. Ahora bien, ¿para qué sirve esto?

Tal vez sea mejor analizar otro ejemplo práctico desde un entorno gráfico:

Se observan 2 terminales abiertas, una corriendo el comando ping ubicada a la izquierda de la pantalla. En la derecha, otra terminal muestra el PID de dicho proceso ping.

Al cerrar la terminal, se observa que el proceso ya no existe en el sistema. Se cierra la terminal, esta envía la señal de hangup a todos sus hijos (incluyendo el proceso corriendo ping), los cuales finalizan.

Ahora se abre una nueva terminal, pero se lanza el ping con nohup:

El nuevo proceso corriendo ping tiene PID 7087.

Ahora se cierra la terminal nuevamente, pero esta vez el proceso ping continúa corriendo en segundo plano, tal como se puede comprobar en la salida de ps. Notar además que no tiene una TTY (terminal que lo controle) asociada (es por ello que aparece el caracter ? en la columna TTY de la salida de ps).

Al igual que en el ejemplo anterior, para terminar este proceso es posible enviar la señal SIGKILL o SIGTERM.

Como conclusión, el uso de nohup nos permite mantener procesos en segundo plano en ejecución, a pesar de cerrar la terminal desde donde fueron lanzados.

Referencias


Tal vez pueda interesarte


Compartí este artículo