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
- SIGHUP - Wikipedia
man signal
man nohup
- Coreutils - GNU core utilities
- Gestión de procesos en GNU/Linux
- Cómo saber el pid de la sesión actual
man tty
man kill
man 4 null
- "ps aux" explicado
- Cómo listar todos los procesos de un usuario específico
- Resolver "sudo: sorry, you must have a tty to run sudo" en scripts lanzados desde cron