What are the practical differences from a sysadmin point of view when deploying services on a unix based system?
What's the difference between running a program as a daemon and forking it into background with '&'?
4 Answers
For a daemon, what you want is a process that has no tie to anything. At the very least, you want it to be in its own session, not be attached to a terminal, not have any file descriptor inherited from the parent open to anything, not have a parent caring for you (other than init) have the current directory in / so as not to prevent a umount...
To detach from a terminal, you create a new session, however, to create a session, you must not be a group (or session) leader, so best is to fork a new process. Assuming the parent exits, that also means that process will not have a parent anymore and will be adopted by init. Then, close all possible file descriptors, you chdir("/") (one can't close the current working directory to release that resource like for file descriptors, making / the current working directories at least doesn't prevent unmounting directories).
Because that process is a session leader, there's a risk that if it ever opens a terminal device, it becomes the controlling process of that terminal. Forking a second time ensures it doesn't happen.
On the other end, &, in interactive shells, forks and creates a new process group (so as not to be in the terminal's foreground process group), and in non-interactive shells, forks a process and ignores SIGINT in it. It doesn't detach from the terminal, doesn't close file descriptors (though some shells will reopen stdin to /dev/null)...
-
what is the use for chdir("/")? to close file descriptor?Timothy Leung– Timothy Leung2018-12-31 11:57:35 +00:00Commented Dec 31, 2018 at 11:57
-
@TimothyLeung, see edit.Stéphane Chazelas– Stéphane Chazelas2019-01-01 15:16:10 +00:00Commented Jan 1, 2019 at 15:16
-
@StéphaneChazelas How about doing
COMMAND & disown. This detaches the process from the terminal, right ? What's the difference between& disownand daemon assuming I did& disownwith the process running with current directory being/GypsyCosmonaut– GypsyCosmonaut2019-12-18 02:49:44 +00:00Commented Dec 18, 2019 at 2:49
The traditional way of daemonizing is:
fork()
setsid()
close(0) /* and /dev/null as fd 0, 1 and 2 */
close(1)
close(2)
fork()
This ensures that the process is no longer in the same process group as the terminal and thus won't be killed together with it. The IO redirection is to make output not appear on the terminal.
-
5so if a terminal that spawns a background process (&) is closed the background process will also terminate?user1561108– user15611082012-11-23 19:33:40 +00:00Commented Nov 23, 2012 at 19:33
-
9The process will receive SIGHUP when the terminal exits, the default handler for that signal is to terminate the process.Dennis Kaarsemaker– Dennis Kaarsemaker2012-11-23 19:35:18 +00:00Commented Nov 23, 2012 at 19:35
-
12Please add the
&part explanation to your answer. It seems to be incomplete.. if you check the original question.mtk– mtk2012-11-28 16:24:35 +00:00Commented Nov 28, 2012 at 16:24 -
1That's because running things in the background with & doesn't make the process do anything special :)Dennis Kaarsemaker– Dennis Kaarsemaker2012-11-28 17:42:47 +00:00Commented Nov 28, 2012 at 17:42
The difference between running a program/process as a daemon and forking it to the background using the ampersand is basically related to ownership.
Most often, the parent process of a daemon is the init process (the very first process to be started on a Unix system), the daemon being a child of that process means that it is not under your direct control as an non-privileged user. While on the other hand, forking a program/process to the background means that you can at any time call it back to the foreground and/or kill it.
-
1Also to answer the above technical side of detaching a process versus keeping it as a child of the terminal, you can try running "nohup firefox &"Odaym– Odaym2012-11-23 20:01:12 +00:00Commented Nov 23, 2012 at 20:01
With command & Your process will be killed by a SIGHUP signal when the parent dies.
If the program doesn't explicitly support "daemon mode" (that is, ignoring HUP signals), sysadmins can still access some workarounds.
On a bash system, you can use:
(trap '' HUP; command) &
This opens a subshell, traps the HUP signal with an empty handler and ampersand/forks it.
Output might still get redirected to the wrong tty. Or get lost.
You may fix that with &>command.out or 1>output.out and 2>errors.out
You might also have access, on most systems, to the nohup command.
nohup simplifies this process greatly. It's quite standard, but I found many busybox embedded ARM distributions missing it. You just write:
nohup command &
..and you're done. Output gets redirected, IIRC, to nohup.out, but this filename can be changed with an option.
-
2Just to note that with with ZSH you can decouple a
command &later from shell withdisownwhich then works as a post-nohup.math– math2013-09-24 07:26:55 +00:00Commented Sep 24, 2013 at 7:26