Nohup and Disown
When we log out or type exit
in a terminal, a hangup signal is sent to the shell,
terminating all its child processes.
The term used is hungup
, as computer users from the last century used modems to connect their
terminals to mainframes. When they hung up the phone, a SIGHUP was sent, and the connection was
terminated.
However, often we want to start a program and let it continue running even after we log out or close
the terminal emulator window.
Something similar can be done with GNU Screen or Tmux, but opening these programs just for this
purpose seems like overkill, besides, some computers do not have Screen installed, and this is not a
valid option to use in scripts.
Nohup
For these cases, there is nohup (“no hangup”), which makes the process immune to SIGHUP.
In my bash, just precede the command with nohup
and send it to the background (&
), and we can
close the terminal without any issues:
julio@julio-acer ~ $ nohup dropboxd &
But the same does not work in 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.
Trying to exit
again will abruptly terminate the program.
This happens because there are still connections to stdin, stdout, and stderr. If we redirect them
to /dev/null
(or another file), we can exit the shell (exit
or logout
) without any issues:
julio@julio-acer ~> nohup dropboxd &> /dev/null < /dev/null &!
julio@julio-acer ~> exit
Disown
But what if you started a program without nohup
and want to log out without having to terminate
it?
In Bash and ZSH, there is the disown command, which disassociates a job from the current shell (removing it from the job list). This allows you to close the shell without interrupting the job.
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
From man bash
, we have:
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.
An interesting option is -h
, which makes disown behave exactly like nohup. However, this option is
exclusive to Bash’s disown and does not work in ZSH.
We can also call disown
along with the program. The functionality is almost the same as nohup
,
and since I don’t need to worry about redirecting streams (stdin
, stdout
, stderr
), I almost
always use disown
instead of nohup
:
julio@julio-acer ~> dropboxd& disown && exit