70

What are the implications of running a script as a daemon versus using nohup?

I know what the difference is in terms of forking processes etc., but what impact does that have on my script?

Trott
  • 66,479
  • 23
  • 173
  • 212
Hortitude
  • 13,638
  • 16
  • 58
  • 72

4 Answers4

80

The nohup command is the poor man's way of running a process as a daemon. As Bruno Ranschaert noted, when you run a command in an interactive shell, it has a controlling terminal and will receive a SIGHUP (hangup) signal when the controlling process (typically your login shell) exits. The nohup command arranges for input to come from /dev/null, and for both output and errors to go to nohup.out, and for the program to ignore interrupts, quit signals, and hangups. It actually still has the same controlling terminal - it just ignores the terminals controls. Note that if you want the process to run in the background, you have to tell the shell to run it in the background - at least on Solaris (that is, you type 'nohup sleep 20 &'; without the ampersand, the process runs synchronously in the foreground).

Usually, a process run via nohup is something that takes time, but which does not hang around waiting for interaction from elsewhere.

Typically (which means if you try hard, you can find exceptions to these rules), a daemon process is something which lurks in the background, disconnected from any terminal, but waiting to respond to some input of some sort. Network daemons wait for connection requests or UDP messages to arrive over the network, do the appropriate work and send a response back again. Think of a web server, for example, or a DBMS.

When a process fully daemonizes itself, it goes through some of the steps that the nohup code goes through; it rearranges its I/O so it is not connected to any terminal, detaches itself from the process group, ignores appropriate signals (which might mean it doesn't ignore any signals, since there is no terminal to send it any of the signals generated via a terminal). Typically, it forks once, and the parent exits successfully. The child process usually forks a second time, after fixing its process group and session ID and so on; the child then exits too. The grandchild process is now autonomous and won't show up in the ps output for the the terminal where it was launched.

You can look at Advanced Programming in the Unix Environment, 3rd Edn by W Richard Stevens and Stephen A Rago, or at Advanced Unix Programming, 2nd Edn by Marc J Rochkind for discussions of daemonization.

I have a program daemonize which will daemonize a program that doesn't know how to daemonize itself (properly). It was written to work around the defects in a program which was supposed to daemonize itself but didn't do the job properly. Contact me if you want it - see my profile.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 13
    Not sure why you call it poor man's. It does the right thing if you want to make your process a daemon, apart from that it doesn't disconnect from the controlling terminal, which on practise doesn't matter. Second, you are calling it wrong, the correct form is `(nohup sleep 20 &)`, i.e. parens disconnect it from the process group leader, so that it doesn't receive signals for that process group. – Maxim Egorushkin Oct 04 '11 at 09:15
  • 1
    @MaximYegorushkin The parens don't make any difference (far as I can see). Running any program from a shell always makes that prog a group leader. Try this and you'll see the PGID always matches the PID: `perl -e 'system "ps -fjp $$"'`. Also, the ampersand is not inherent in nohup, so even that is a difference between nohup and daemon. I'm going to add my own answer with even more diffs. – Kelvin Jan 18 '12 at 17:44
  • 6
    @Kelvin: The parentheses in `(nohup sleep 20 &)` do make a difference. They specify a sub-shell. Inside the sub-shell, the `nohup` command executes the `sleep` command in the background. When it returns, the sub-shell exits, so the `sleep` is orphaned, no longer 'owned' by the current shell. – Jonathan Leffler Jan 18 '12 at 18:46
  • @JonathanLeffler Ok I see a difference now - the parent PID is 1 rather than the shell's PID. But I still don't see any difference wrt it becoming a process group leader. It's also still part of the same session, so it's not completely "orphaned". In any case, the parens don't seem relevant to the nohup/daemon distinction. – Kelvin Jan 18 '12 at 18:55
  • Why doesn't a daemon show up in "ps" command? How does one stop/kill a daemon then? – Sriman Aug 28 '23 at 14:06
  • @Sriman: There are many ways to see daemons in the output of `ps`. Typing `ps -ef` will give you a listing of all the processes on the system; you can post-process the output with `grep` — to look for a specific daemon, use `grep -e '[d]aemon'`, perhaps with `-w` too. The `[d]aemon` string won't be matched, so you don't see your grep command in the output. There are other options for `ps` — look at the POSIX specification of [`ps`](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html), or your system's man page (e.g. [`ps(1)`](http://man7.org/linux/man-pages/man1/ps.1.html)) – Jonathan Leffler Aug 28 '23 at 14:31
47

Becoming a daemon

This link has a good list of steps a process should take in becoming a daemon:

https://web.archive.org/web/20120328110436/http://www.steve.org.uk/Reference/Unix/faq_2.html#SEC16

I can't copy the list verbatim because of copyright (see the About section), but here's the summary:

  1. fork (first time) -- so we aren't a group leader, and let the parent exit.
  2. call setsid() -- to become leader of a new session. This call only works if we are not a group leader. This new session has no controlling terminal.
  3. fork (second time) -- so we aren't a session leader (and thus can't regain a controlling terminal), and let the parent exit.
  4. cd to root directory -- so we don't prevent other directories from being umount-ed.
  5. set umask to desired value (optional) -- because we could've inherited a mask we didn't want.
  6. close stdin, stdout, stderr (or just reopen them to point elsewhere)

nohup

What nohup does:

  • If stdout and stderr are connected to a terminal, redirects them to nohup.out
  • ignores SIGHUP

Similarities and Differences

Notice how the only common actions are redirecting stdout and stderr. To be a daemon doesn't even require ignoring SIGHUP.

nohup doesn't require you to use '&' to background the process - meaning you can still use ctrl-c to send SIGINT. The process still responds to keyboard input. It also doesn't change stdin automatically, so it's recommended that you do it yourself via "< /dev/null".

Please do not confuse nohup with other features normally used with it (e.g. backgrounding). The OP asked specifically about nohup.

In Practice

In terms of practicality, when you want to start a one-time long-running process which should continue when the shell exits, you'll want to use nohup, but you'll also want to combine it with backgrounding and redirecting of stdin. A one-time job isn't worth making a daemon, but some of the properties of a daemon can still be useful with a nohup job, like "cd /".

Periodic tasks on a regular schedule are best run via cron (or some other scheduler).

Daemons are best suited for overseeing repeated tasks that don't have a predictable start time. There normally is no definite end time for the daemon process (it's explicitly stopped by a user/another process or by system shutdown). Often daemons are services that respond to applications (clients) or other conditions (e.g. incoming data via on an IO device via unix select()). Other daemons poll for a condition and perform an action in response.

Addendum about controlling terminal

See this page. A quick summary is that a controlling terminal grants unlimited access to its stdin, stdout, stderr. Only one process group may have access to stdin. By default, background process groups can also write to stdout and stderr.

Also, it seems that keyboard signals sent to a terminal are only sent to the process group which has it as a controlling terminal.

Kelvin
  • 20,119
  • 3
  • 60
  • 68
9

In UNIX variants, a process is associated with a terminal process (login shell). So when the terminal process exits, the process is halted as well, because of this association. The nohup prevents a process from exiting when the terminal stops.

A daemon or demon is a process that is started by the system when it starts up, it runs till shutdown, no user asked for it explicitly. So by definition it is not part of a user interaction but belongs to the system.

If you have access to the system as a user, you can use nohup. If you are sysadmin, you can install a deamon process. For the process it does not matter.

Bruno Ranschaert
  • 7,428
  • 5
  • 36
  • 46
  • +1 I stand corrected. Mixed up between daemon and a background process (&). :) – pugmarx Jun 05 '09 at 22:10
  • 1
    Almost right. When a controlling process (group leader) exits all processes in the group get sent SIGHUP optionally followed by SIGCONT. – Maxim Egorushkin Oct 04 '11 at 09:04
  • 6
    Some corrections: A daemon does not need to be a system process; a non-privileged user can run a daemon. A user can interact with a daemon, just not via terminal signals and IO streams (think web server). Daemons can be started at almost any time; they're not restricted to system boot-up. – Kelvin Jan 18 '12 at 18:38
-1

A daemon can't be initiated, while nohup is initiated by the user.

Scott
  • 1,869
  • 3
  • 20
  • 25
swarna
  • 9