772

What are the differences between

$ nohup foo

and

$ foo &

and

$ foo & 
$ disown
Jeff Schaller
  • 66,199
  • 35
  • 114
  • 250
Lesmana
  • 26,889
  • 20
  • 81
  • 86
  • 53
    There is also `foo &!` which should be equal to disowning it right from the start. – user4514 Nov 18 '12 at 19:02
  • 40
    Bash does not support &!. – Jonas Kongslund Jun 03 '13 at 04:35
  • 2
    You can also use `set -m` to enable job control. See http://unix.stackexchange.com/questions/196603/can-someone-explain-in-detail-what-set-m-does – Adam D. Jan 18 '16 at 06:31
  • 3
    Given the age of this question+upvotes I think it worth mentioning : all these are aspects and/or low-tech ways if daemonizing a process. Today, post systemd, a more proper way of daemonizing will usually involve a systemd unit – Rusi Dec 05 '19 at 09:50
  • 5
    "Daemonizing" is one purpose, but there's also the scenario where someone might need to kick off a long-running process and ensure it doesn't get killed when they close their laptop/lose their hotspot/etc, e.g. long-running build, data migration, web crawling, etc – JBRWilkinson Jan 15 '20 at 18:49
  • As [YoungFrog](https://unix.stackexchange.com/users/56415/youngfrog) knows in the mean time, [this answer](https://unix.stackexchange.com/a/352923/318461) mentions `setsid` and how it relates to `disown` and `nohup`. – Cadoiz Nov 14 '22 at 12:07

5 Answers5

818

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 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).
celtschk
  • 10,644
  • 1
  • 19
  • 27
  • 15
    +1 Thanks. What happens when using disown, nohup and & together then? – Tim Apr 02 '15 at 14:27
  • 28
    If you use all three together, the process is running in the background, is removed from the shell's job control and is effectively disconnected from the terminal. – celtschk Apr 02 '15 at 15:46
  • 4
    Thanks. I wonder why [`nohup` alone doesn't save a google-chrome process from being closed, when the terminal from which it was started is closed](http://unix.stackexchange.com/questions/162749/why-is-chromium-browser-killed-when-i-close-the-terminal-despite-nohup)? – Tim Apr 02 '15 at 16:19
  • I couldn't reproduce it until looking at [this answer](http://stackoverflow.com/questions/11421810/nohup-doesnt-work-with-chromium) (which actually is a comment) to a related question. Given that Alt+F4 is a window manager key combination completely unrelated to the shell, I guess it is something the window manager does. However it doesn't seem to go via X events, as `xev` doesn't show something that I can recognize as causing a close. – celtschk Apr 02 '15 at 18:06
  • 3
    what's the difference between `disown %1` and `disown -h %1`? The second one will keep as a regular job(but ignores the HUP signal) until the terminal exit? – schemacs Nov 03 '15 at 00:07
  • `nohup` having no nohup.out [tip](http://stackoverflow.com/a/10408906/1422630) `nohup command /dev/null 2>&1 &` completely detached from terminal – Aquarius Power Feb 07 '16 at 01:04
  • "the program will fail as soon as it tries to read from standard input or write to standard output" Won't it receive SIGPIPE before that (as soon as the controlling program is terminated)? – Vladimir Panteleev May 30 '16 at 11:38
  • 7
    Maybe worth including `(foo&)` subshell – jiggunjer Aug 25 '16 at 12:32
  • How to tell if the shell will send `SIGHUP` to the process when using `&`? – flyingfoxlee Sep 06 '16 at 09:02
  • 2
    Be aware, if the process uses a customized SIGHUP handle, nohup will fail to mask the SIGHUP thus might not clearly segregate the process from the shell. So combining disown and nohup is safer. – Amos Jun 17 '17 at 09:06
  • Then does `nohup command & disown` make any sense? Is it any way better than `nohup command &` or `command & disown` if I want to detach the process from terminal as far as possible? – Mohammed Shareef C Aug 24 '17 at 12:02
  • 10
    As noted at https://unix.stackexchange.com/questions/446211/ , the received wisdom that `nohup` disconnects from the controlling terminal is wrong. `nohup` closes some standard I/O streams and opens them elsewhere. It does not change session, attempt to affect the session's connection to a controlling terminal, or deal in process groups. – JdeBP May 29 '18 at 08:14
  • 1
    `disown` not fail when it write to standard output, but when it need standard input. – roachsinai Nov 18 '19 at 16:55
  • @roachsinai: Read carefully: If you *close the terminal* after disown, then write fails. I just tested it explicitly, to be fully sure, but it's actually obvious: If the terminal to write on *no longer exists* then you certainly cannot write to it. This is unlike nohup which redirects the output, such that even the terminal disappearing doesn't cause any trouble. – celtschk Nov 27 '19 at 18:36
  • Good answer but some imprecision. In the first part, _"(...)SIGHUP(...)normally causes the process to terminate. Otherwise the shell waits (is blocked) until the process terminates."_ Not quite true, if you hit ^Z (i.e., send `SIGTSTP`) the process is just stopped, not terminated, the shell is no more blocked: you can do whatever you want, and with `bg` you can continue the stopped job in background (as with &), or `fg` to put it back to fg (both send `SIGCONT`). – Max Jun 20 '20 at 22:49
  • @Max: Thanks for noting that inaccuracy; I've now added “or gets stopped” to that sentence. – celtschk Jun 21 '20 at 06:19
  • I am a little bit confused after reading the answer thoroughly. Will the process I `disown` still keep working if I close the current terminal? Because you said for `disown`, "*..it still leaves it connected to the terminal.*" . – Rick Jan 15 '21 at 15:51
  • 1
    @Rick: It will continue to run, but any attempt to write to the terminal (e.g. by writing to standard output if not redirected) will fail (because the terminal no longer exists). What this means for the process depends on the running program; some programs don't check for errors on standard output, those will just run normally but not actually output anything. Otherwise it will do whatever it is programmed to do when writing fails. But the point is, as long as the terminal is *not* closed, any output of the program will still appear there. – celtschk Jan 15 '21 at 16:28
  • celtschk / @JdeBP and others - when the program is run normally (without & or nohup) and later disowned, for this disown case - even though the process is disowned and run in bg, is not the program still attached to stdout/stderr of the terminal. So when the terminal gets exited or killed, won't the program stop as it's std*** connections are lost – samshers Dec 27 '21 at 07:20
  • 1
    @samshers: As long as the process doesn't try to read from stdin or write to stdout/stderr, it doesn't matter that the terminal disappeared; the process will just continue to run. – celtschk Dec 27 '21 at 20:56
  • @celtschk - do you mean after `disown`ing or even without disowing. – samshers Dec 27 '21 at 21:00
  • 1
    @samshers: After disown. – celtschk Dec 28 '21 at 19:29
  • @celtschk -[sorry i am repeating myself](https://unix.stackexchange.com/questions/3886/difference-between-nohup-disown-and/148698?noredirect=1#comment1291989_148698). Then how does it work. I have checked/tested it. Start a process normally. then ctr+z, then bg, then disown, then close the terminal. And the process is still up and running. So wondering how. After doing bg, the process is resumed and still connected to the terminals ( stdout), i can see the logs printing. ....cont... – samshers Dec 28 '21 at 19:52
  • ....cont... And closing the terminal should disconnect the process stdout and the process should fail. But it's not failing and still running as i can see from another terminal. Am i clear or i can write further. – samshers Dec 28 '21 at 19:52
  • Would `nohup` be basically equivalent to `foo &> nohup.out &; disown;`? – c1moore May 06 '22 at 19:55
  • 1
    I just signed up, so I can upvote this glorious answer. – SinaMobasheri Nov 27 '22 at 18:37
  • "The process in principle also inherits stdin, but as soon as it tries to read from stdin, it is halted." -> Does "halted" mean "killed"? – robertspierre Aug 11 '23 at 04:32
193

Using & causes the program to run in the background, so you'll get a new shell prompt instead of blocking until the program ends. nohup and disown are largely unrelated; they suppress SIGHUP (hangup) signals so the program isn't automatically killed when the controlling terminal is closed. nohup does this when the job first begins. If you don't nohup a job when it begins, you can use disown to modify a running job; with no arguments it modifies the current job, which is the one that was just backgrounded

Michael Mrozek
  • 91,316
  • 38
  • 238
  • 232
  • 14
    Minor difference between nohup and disown: the disown command will remove it from your jobs list; nohup will not. – Shawn J. Goff Nov 09 '10 at 16:41
  • 217
    `nohup` and `disown` both can be said to suppress `SIGHUP`, but in different ways. `nohup` makes the program ignore the signal initially (the program may change this). `nohup` also tries to arrange for the program not to have a controlling terminal, so that it won't be sent `SIGHUP` by the kernel when the terminal is closed. `disown` is purely internal to the shell; it causes the shell not to send `SIGHUP` when it terminates. – Gilles 'SO- stop being evil' Nov 09 '10 at 18:26
  • 28
    @Gilles, your comment is worth an answer of itself. – Lesmana Nov 10 '10 at 18:30
  • 6
    Just a clarification on @ShawnJ.Goff 's comment pertaining to `disown` removing the job from the jobs list. If you don't specify an option, it does remove it from the jobs list. *However*, if you specify the `-h` option, each jobspec is **not** removed from the table. Instead, it makes it so that `SIGHUP` is not sent to the job if the shell receives a `SIGHUP`. – tacotuesday Nov 13 '13 at 06:54
  • 5
    Just to clarify, using `&` does not give you a terminal, it detaches **`stdin`** from the process and causes it to run in the background, but both **`stdout`** and **`stderr`** is still attached to the current tty. This means that you may get text from different programs mixed up together, which can be quite annoying if you do `gimp &` and get lots of GTK+ errors while trying to use that tty for something else. – Frank Jun 05 '14 at 21:18
  • Michael / @Gilles'SO-stopbeingevil' and others - when the program is run normally (without & or nohup) and later disowned, for this disown case - even though the process is disowned and run in bg, is not the program still attached to stdout/stderr of the terminal. So when the terminal gets exited or killed, won't the program stop as it's std*** connections are lost – samshers Dec 27 '21 at 07:17
  • @samshers After the program disappears, if the program tries to write to stdout or stderr, the write will fail. What the program decides to do when those writes fail depends on the program. The system won't send a signal for that. Only the loss of the controlling terminal can cause a signal (SIGHUP). – Gilles 'SO- stop being evil' Dec 27 '21 at 11:05
22

Here is my experience trying to run soffice in the background, following a non-terminating command (e.g. tail). For this example I will use sleep 100.

In all the cases below I execute like this:

./scriptfile
<Ctl-C>

&

#!/bin/bash
/opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100

I see soffice logs / by pressing Ctrl-C soffice stops

nohup .. &

#!/bin/bash
nohup /opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100

I don't see soffice logs / by pressing Ctrl-C soffice stops

& disown

#!/bin/bash
/opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard & disown
sleep 100

I see soffice logs / by pressing Ctrl-C soffice stops

setsid .. &

#!/bin/bash
setsid /opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100

I see soffice logs / by pressing Ctrl-C soffice DOES NOT STOP

To save space:
nohup setsid .. : does not show logs / soffice DOES NOT STOP on Ctrl-C
nohup with & disown at the end : does not show logs / soffice stops on Ctrl-C

Marinos An
  • 779
  • 7
  • 11
  • 6
    While I appreciate the effort of mentioning setsid and showing what​ happens in that specific situation, I'd like to see a more thorough answer. In particular the difference and similarities of each solution, both visible (what happens when close the shell or the terminal, where does the output go,...) and invisible (how things are done under the hood and their implications). The accepted answer is a nice base for that. – YoungFrog Mar 21 '17 at 20:58
  • 2
    For me, with `nohup ⟨command⟩ & disown` the created process does not stop on `Ctrl+C`. – k.stm Jun 27 '18 at 20:23
  • @k.stm Did you try `soffice`? `soffice` command seems to have something different. So I considered adding it here as a rule exception. e.g. when using: `nohup .. &` , pressing `Ctrl-c` normally does not cause the command to stop, but with `soffice` it does. I wait until someone steps on this and explains why this happens with soffice :) – Marinos An Jun 28 '18 at 13:29
  • @MarinosAn Yes, I did. I ran `nohup soffice &` and pressed `Ctrl+C`. Nothing happened, as expected. – k.stm Jul 05 '18 at 10:58
14

Short answer:

  • use & when you want your command to run in the background, so you can run the next one without waiting for it to finish
  • use nohup if you want your command to ignore the SIGHUP signal, so when you close the terminal or log out from ssh session the process keeps running
  • use disown if you forget to run the command with nohup and want to log out without killing the process (it will disown all processes in the background). To put a process in the background and disown it:
    1. Ctrl+Z to pause process
    2. bg to put stopped process to the background
    3. disown to make process ignore terminal termination
ivanjermakov
  • 233
  • 3
  • 8
  • for the last disown case - even though the process is disowned and run in bg, is not the program still attached to stdout/stderr of the terminal. So when the terminal gets exited or killed, won't the program stop as it's std*** connections are lost – samshers Dec 27 '21 at 07:15
1

See also the daemonize(1) utility, which handles all of the chores about running a "true background" process. As of its docs:

daemonize runs a command as a Unix daemon. As defined in W. Richard Stevens' 1990 book, Unix Network Programming (Addison-Wesley, 1990), a daemon is “a process that executes `in the background' (i.e., without an associated terminal or login shell) either waiting for some event to occur, or waiting to perform some specified task on a periodic basis.” Upon startup, a typical daemon program will:

  • Close all open file descriptors (especially standard input, standard output and standard error)
  • Change its working directory to the root filesystem, to ensure that it doesn't tie up another filesystem and prevent it from being unmounted
  • Reset its umask value
  • Run in the background (i.e., fork)
  • Disassociate from its process group (usually a shell), to insulate itself from signals (such as HUP) sent to the process group
  • Ignore all terminal I/O signals
  • Disassociate from the control terminal (and take steps not to reacquire one)
  • Handle any SIGCLD signals

Most programs that are designed to be run as daemons do that work for themselves. However, you'll occasionally run across one that does not. When you must run a daemon program that does not properly make itself into a true Unix daemon, you can use daemonize to force it to run as a true daemon.

It superseeds all of the &/nohup/disown mess.

Luchostein
  • 566
  • 4
  • 7