CTS 1106 (Intro to Unix/Linux):
The nohup Command — A Tutorial

 

©2008 by Wayne Pollock, Tampa Florida USA

Sometimes it is a good idea to start running some process (or job) and log out, letting the job continue to run.  Before you can log off you need to put the job in background, such as by added & at the end of the command line.  A good use of this would be to begin a lengthy task such as a big file download and log out, letting the download continue:

wget ftp://example.com/big.file &

However, when a shell terminates any background jobs started by that shell are sent the SIGHUP signal to kill them.  To have a job continue to run after you log out (or close an xterm window) the job must ignore this signal.

Another issue is that the job is no longer attached to any session (i.e. input and output are no longer connected to any terminal) so you must redirect its output or it will be lost.  Since it won't be possible for the job to read from the terminal, any interactive job would be stuck waiting for input that can never arrive!

The nohup command solves these issues.  It starts a new shell, one that ignores SIGHUP.  That shell then runs the provided command line (signal handling is an exported part of the environment and thus inherited by the commands run by that shell).  You still must run the command in the background.  Typically nohup is used this way:

nohup wget ftp://example.com/big.file &

The output (both standard output and standard error) of the shell started by nohup is redirected to ./nohup.out (or ~/nohup.out if the current directory isn't writable), unless you redirect it elsewhere.

Standard input must be redirected (</dev/null) or ssh may not close when you log out!  Some versions of nohup don’t have this problem (e.g., Gnu), but for portability always redirect stdin.

Bash can automatically ignore SIGHUP for any jobs started in the background, by setting shopt -u huponexit.  Bash also provides a built-in disown command.  This can be used to make an already running job ignore SIGHUP:

disown -h job

You specify a job with disown the same way you would with the kill command: by a process's PID, by its job number (e.g. %1), or by its name (e.g. %wget).

See also the (non-POSIX) screen command, which allows you to suspend an interactive session and log out (allowing background jobs to continue to run).  Later you can re-open that session, possibly from a different location.