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 typed `foo`: * The process running `foo` is created. * The process inherits stdin, stdout, and stderr from the shell. Therefore it is also connected to the same terminal. * If the shell receives a `SIGHUP`, it also sends a `SIGHUP` to the process (which normally causes the process to terminate). * Otherwise the shell waits (is blocked) until the process terminates or gets stopped. Now, let's look what happens if you put the process in the background, that is, type `foo &`: * The process running `foo` is created. * The process inherits stdout/stderr from the shell (so it still writes to the terminal). * The process in principle also inherits stdin, but as soon as it tries to read from stdin, it is halted. * It is put into the list of background jobs the shell manages, which means especially: * It is listed with `jobs` and can be accessed using `%n` (where `n` is the job number). * It can be turned into a foreground job using `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). * If the shell received a `SIGHUP`, it also sends a `SIGHUP` to the process. Depending on the shell and possibly on options set for the shell, when terminating the shell it will also send a `SIGHUP` 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 a `SIGHUP` 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 by `xterm` or `ssh`, and the controlling program is terminated, by closing the xterm or terminating the [SSH][1] 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: * It closes standard input (the program will *not* be able to read any input, even if it is run in the foreground. it is not halted, but will receive an error code or `EOF`). * It redirects standard output and standard error to the file `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. * It prevents the process from receiving a `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 foreground `nohup` job is more or less useless, you'd generally put it into the background using `&`). For example, unlike with `disown`, 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 a `SIGHUP`. 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 to `nohup.out` and shields it from `SIGHUP`. One of the effects (the naming one) is that the process won't receive any sent `SIGHUP`. It is completely independent from job control and could in principle be used also for foreground jobs (although that's not very useful). [1]: http://en.wikipedia.org/wiki/Secure_Shell