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:
- run
emacs &
(by default should run in a separate X window).
- 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.
SoX wants/needs input & output... by typing 'play xxxx' in the console, you're running it normally, with stdin & stdout (& stderr) all connected.
When you background the job (with &), it starts, then is paused since it's waiting for access to stdin & stdout.
Same thing occurs when you 'nohup' a job. If it needs keyboard input, it'll "block", and get paused by the system until it receives access to stdin.
disown'ing a process effectively cuts it off from stdin & stdout which were connected to the console which started the process.
It's still "running", but is blocked (paused) by the system since it's waiting for access to stdin & stdout.
Best Answer
Let's first look at what happens if a program is started from an interactive shell (connected to a terminal) without
&
(and without any redirection). So let's assume you've just typedfoo
:foo
is created.SIGHUP
, it also sends aSIGHUP
to the process (which normally causes the process to terminate).Now, let's look what happens if you put the process in the background, that is, type
foo &
:foo
is created.jobs
and can be accessed using%n
(wheren
is the job number).fg
, in which case it continues as if you would not have used&
on it (and if it was stopped due to trying to read from standard input, it now can proceed to read from the terminal).SIGHUP
, it also sends aSIGHUP
to the process. Depending on the shell and possibly on options set for the shell, when terminating the shell it will also send aSIGHUP
to the process.Now
disown
removes the job from the shell's job list, so all the subpoints above don't apply any more (including the process being sent aSIGHUP
by the shell). However note that it still is connected to the terminal, so if the terminal is destroyed (which can happen if it was a pty, like those created byxterm
orssh
, and the controlling program is terminated, by closing the xterm or terminating the SSH connection), the program will fail as soon as it tries to read from standard input or write to standard output.What
nohup
does, on the other hand, is to effectively separate the process from the terminal:EOF
).nohup.out
, so the program won't fail for writing to standard output if the terminal fails, so whatever the process writes is not lost.SIGHUP
(thus the name).Note that
nohup
does not remove the process from the shell's job control and also doesn't put it in the background (but since a foregroundnohup
job is more or less useless, you'd generally put it into the background using&
). For example, unlike withdisown
, the shell will still tell you when the nohup job has completed (unless the shell is terminated before, of course).So to summarize:
&
puts the job in the background, that is, makes it block on attempting to read input, and makes the shell not wait for its completion.disown
removes the process from the shell's job control, but it still leaves it connected to the terminal. One of the results is that the shell won't send it aSIGHUP
. Obviously, it can only be applied to background jobs, because you cannot enter it when a foreground job is running.nohup
disconnects the process from the terminal, redirects its output tonohup.out
and shields it fromSIGHUP
. One of the effects (the naming one) is that the process won't receive any sentSIGHUP
. It is completely independent from job control and could in principle be used also for foreground jobs (although that's not very useful).