When do you need 'nohup' if you're already forking using '&'?

First of all, every time you execute a command, you shell will fork a new process, regardless of whether you run it with & or not. & only means you're running it in the background.

Note this is not very accurate. Some commands, like cd are shell functions and will usually not fork a new process. type cmd will usually tell you whether cmd is an external command or a shell function. type type tells you that type itself is a shell function.

nohup is something different. It tells the new process to ignore SIGHUP. It is the signal sent by the kernel when the parent shell is closed.

To answer your question do the following:

  1. run emacs & (by default should run in a separate X window).
  2. on the parent shell, run exit.

You'll notice that the emacs window is killed, despite running in the background. This is the default behavior and nohup is used precisely to modify that.

Running a job in the background (with & or bg, I bet other shells have other syntaxes as well) is a shell feature, stemming from the ability of modern systems to multitask. Instead of forking a new shell instance for every program you want to launch, modern shells (bash, zsh, ksh, ...) will have the ability to manage a list of programs (or jobs). Only one of them at a time can be at the foreground, meaning it gets the shell focus. I wish someone could expand more on the differences between a process running in the foreground and one in the background (the main one being acess to stdin/stdout).

In any case, this does not affect the way the child process reacts to SIGHUP. nohup does.


Is it ever useful to do nohup ... &? Yes. If you just start a process "in the background" with &, that new process still has membership in the original shell's "process group". If that shell or the process group gets certain signals (SIGHUP, for example), by default they exit. This means that if you run a process with & from a shell started by an xterm, or rxvt or some other windowing terminal emulator, when you close the window, the background process gets a SIGHUP. Most casually-written code does not handle SIGHUP, and therefore exits.

If you do nohup ... &, the nohup command sets SIGHUP to ignored, and then execs the command. That newly exec'ed command keeps the signal mask that nohup setup, unless the command does some signal handling itself. If you close the xterm or rxvt or whatever, the kernel delivers SIGHUP to the command's process, which is ignored. It keeps running.

Doing a nohup on a command allows it to keep running after you close the xterm, or you log off.

Tags:

Shell

Fork

Nohup