Nohup y disown

Cuando cerramos sesión o escribimos exit en un terminal, se envía una señal hangup al
shell, que termina todos sus procesos hijos.
El término es hangup porque la gente de la informática del siglo pasado conectaba sus terminales
a los mainframes por módem. Cuando “colgaban el teléfono” (hung up) se enviaba un SIGHUP y la
conexión terminaba.
Pero muchas veces queremos arrancar un programa y dejarlo corriendo aunque cerremos la sesión o la
ventana del emulador de terminal.
Algo parecido se puede hacer con GNU Screen o Tmux, pero abrirlos solo para eso parece excesivo;
además, algunos ordenadores no tienen Screen instalado y no sirve para usarlo en scripts.
Nohup
Para estos casos existe nohup ("no hangup"), que hace al proceso inmune a SIGHUP.
En mi bash basta con anteponer nohup al comando y mandarlo a segundo plano (&) para poder cerrar
el terminal sin problemas:
julio@julio-acer ~ $ nohup dropboxd &
Pero lo mismo no funciona en ZSH:
julio@julio-acer ~> nohup dropboxd &
[1] 13434
nohup: ignoring input and appending output to ‘nohup.out’
julio@julio-acer ~> exit
zsh: you have running jobs.
Si intentas exit otra vez, el programa termina de golpe.
Esto pasa porque siguen existiendo conexiones con stdin, stdout y stderr. Si las redirigimos a
/dev/null (u otro archivo) podremos salir del shell (exit o logout) sin problemas:
julio@julio-acer ~> nohup dropboxd &> /dev/null < /dev/null &!
julio@julio-acer ~> exit
Disown
¿Y si arrancaste un programa sin nohup y quieres cerrar sesión sin matarlo?
En Bash y ZSH existe el comando disown, que desvincula un trabajo del shell actual (lo quita de la job list). Así se puede cerrar el shell sin que el trabajo se interrumpa.
julio@julio-acer ~> dropboxd
^Z
[1] + 23042 suspended dropboxd
julio@julio-acer ~> bg %1
[1] + 23042 continued dropboxd
julio@julio-acer ~> jobs
[1] + running dropboxd
julio@julio-acer ~> disown %dropboxd
julio@julio-acer ~> jobs
julio@julio-acer ~> ps 23042
PID TTY STAT TIME COMMAND
23042 pts/7 SNl 0:02 /opt/dropbox/dropbox
julio@julio-acer ~> exit
De man bash:
disown
\[-**ar**\]\[**-h**\]\[_jobspec_ ...\]
Without options, each jobspec is removed from the table of active jobs. If jobspec is not present, and neither -a nor -r is supplied, the shell’s notion of the current job is used. If the -h option is given, each jobspec is not removed from the table, but is marked so that SIGHUP is not sent to the job if the shell receives a SIGHUP. If no jobspec is present, and neither the -a nor the -r option is supplied, the current job is used. If no jobspec is supplied, the -a option means to remove or mark all jobs; the -r option without a jobspec argument restricts operation to running jobs. The return value is 0 unless a jobspec does not specify a valid job.
Una opción interesante es -h, que hace que disown se comporte igual que nohup. Pero es exclusiva
del disown de Bash y no funciona en ZSH.
También podemos llamar a disown junto con el programa. Hace prácticamente lo mismo que nohup y,
como no tengo que preocuparme de redirigir los flujos (stdin, stdout, stderr), casi siempre
uso disown en lugar de nohup:
julio@julio-acer ~> dropboxd& disown && exit

Soy un ingeniero informático brasileño radicado en Alemania, apasionado por la tecnología, la ciencia, la fotografía y los idiomas.
Llevo programando cerca de dos décadas, explorando desde apps móviles y desarrollo web hasta aprendizaje automático. Hoy me enfoco en SRE en la nube e ingeniería de datos.
Soy voluntario en las comunidades de open source y Python, ayudando a organizar PyCon DE y PyData Berlin, dando mentorías y contribuyendo con código y traducciones.
En mi blog comparto consejos de Linux, guías de configuración y notas personales que escribí como referencia futura. Espero que también sean útiles para otras personas. El contenido está disponible en varios idiomas.
Visita mi galería para ver algunas de mis fotografías.
Fuera del teclado, me encontrarás en conciertos, tocando el clarinete, en bicicleta, buceando o explorando nuevos lugares, culturas y cocinas.
¡Siempre feliz de conectar! 🙂