6

It is commonly said that "&" puts the process into background execution, but that process would be killed when terminal is closed. But from what I see, everything I sent into background was continuing to be active long after I close the terminal. For example:

$ tail -f /var/log/messages/ &

That process would continue to run, even if there are no other process under the user that launched it, and all terminals are long gone. Why is that?

Rogach
  • 6,303

3 Answers3

7

Just a guess (this is bash specific): the documentation for the huponexit shell option says

If set, Bash will send SIGHUP to all jobs when an interactive login shell exits

On my system, it does not seem to be set by default. You can check with

shopt -p huponexit

If the output includes -u, it is unset.

jw013
  • 51,212
5

A process put in the background with '&' rather than nohup will die when it requires the terminal for input or output and discovers it's not there. In this case, tail will probably exit when something writes to /var/log/messages, although there might be some buffer issue that would delay it until more than one message is written.

Starting a process with ./foo > /dev/null 2&1 < /dev/null is approximately equivalent to starting with nohup. Basically all nohup does is take care of redirecting any input and output that isn't already redirected away from the terminal.

Paul Tomblin
  • 1,678
3

The ampersand & will put the process into the background. File descriptors (stdout, stderr, stdin) are unaffected. On shell exit, the shell will send SIGHUP to everything it spawned, so when this shell closes, the background process will receive SIGHUP and probably terminate. In some shells (bash, zsh) you can prevent this by using the command disown which will tell the shell to not send it SIGHUP on shell closing, and the process will continue to run.

You can also perform the equivalent of 'backgrounding using an ampersand' by sending SIGSTOP (usually Ctrl-Z in your terminal) and then backgrounding the process (bg).

nohup works by ignoring SIGHUP. This signal disposition is then passed to the child process you run. nohup also checks to see where stdout is going, and if its going to the terminal, it redirects stdout and stderr to a file. After the signal disposition change, and the possible redirect, it runs your process in the background.

So, whats the difference?

A background process doesn't ignore SIGHUP, though you can tell your shell not to send it with disown. Unless prevented, nohup redirects stdout to nohup.out files, which I tend to hate, if only that I need to delete nohup.out files randomly scattered on my disk.

There is also setsid, which makes your process a process group leader. A process group leader will never get SIGHUP sent to it by any shell. setsid does not much with stdout/stderr, and I tend to use setsid instead of nohup.