Best way to make a shell script daemon?

Shawn J. Goff picture Shawn J. Goff · Aug 7, 2010 · Viewed 196.8k times · Source

I'm wondering if there is a better way to make a daemon that waits for something using only sh than:

#! /bin/sh
trap processUserSig SIGUSR1
processUserSig() {
  echo "doing stuff"
}

while true; do
  sleep 1000
done

In particular, I'm wondering if there's any way to get rid of the loop and still have the thing listen for the signals.

Answer

Ken B picture Ken B · Jun 6, 2012

Just backgrounding your script (./myscript &) will not daemonize it. See http://www.faqs.org/faqs/unix-faq/programmer/faq/, section 1.7, which describes what's necessary to become a daemon. You must disconnect it from the terminal so that SIGHUP does not kill it. You can take a shortcut to make a script appear to act like a daemon;

nohup ./myscript 0<&- &>/dev/null &

will do the job. Or, to capture both stderr and stdout to a file:

nohup ./myscript 0<&- &> my.admin.log.file &

However, there may be further important aspects that you need to consider. For example:

  • You will still have a file descriptor open to the script, which means that the directory it's mounted in would be unmountable. To be a true daemon you should chdir("/") (or cd / inside your script), and fork so that the parent exits, and thus the original descriptor is closed.
  • Perhaps run umask 0. You may not want to depend on the umask of the caller of the daemon.

For an example of a script that takes all of these aspects into account, see Mike S' answer.