ll.daemon – Forking daemon processes

This module can be used on UNIX to fork a daemon process. It is based on Jürgen Hermann’s Cookbook recipe.

An example script might look like this:

from ll import daemon

counter = daemon.Daemon(
   stdin="/dev/null",
   stdout="/tmp/daemon.log",
   stderr="/tmp/daemon.log",
   pidfile="/var/run/counter/counter.pid",
   user="nobody"
)

if __name__ == "__main__":
   if counter.service():
      import sys, os, time
      sys.stdout.write(f"Daemon started with pid {os.getpid()}\n")
      sys.stdout.write(f"Daemon stdout output\n")
      sys.stderr.write(f"Daemon stderr output\n")
      c = 0
      while True:
         sys.stdout.write(f"{c}: {time.ctime(time.time())}\n")
         sys.stdout.flush()
         c += 1
         time.sleep(1)
class ll.daemon.Daemon[source]

Bases: object

The Daemon class provides methods for starting and stopping a daemon process as well as handling command line arguments.

__init__(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null', pidfile=None, user=None, group=None)[source]

The stdin, stdout, and stderr arguments are file names that will be opened and be used to replace the standard file descriptors in sys.stdin, sys.stdout, and sys.stderr. These arguments are optional and default to "/dev/null". Note that stderr is opened unbuffered, so if it shares a file with stdout then interleaved output may not appear in the order that you expect.

pidfile must be the name of a file. start() will write the pid of the newly forked daemon to this file. stop() uses this file to kill the daemon.

user can be the name or uid of a user. start() will switch to this user for running the service. If user is None no user switching will be done.

In the same way group can be the name or gid of a group. start() will switch to this group.

openstreams()[source]

Open the standard file descriptors stdin, stdout and stderr as specified in the constructor.

handlesighup(signum, frame)[source]

Handle a SIG_HUP signal: Reopen standard file descriptors.

handlesigterm(signum, frame)[source]

Handle a SIG_TERM signal: Remove the pid file and exit.

switchuser(user, group)[source]

Switch the effective user and group. If user and group are both None nothing will be done. user and group can be an int (i.e. a user/group id) or str (a user/group name).

start()[source]

Daemonize the running script. When this method returns the process is completely decoupled from the parent environment.

stop()[source]

Send a SIGTERM signal to a running daemon. The pid of the daemon will be read from the pidfile specified in the constructor.

argparser()[source]

Return an argparse parser for parsing the command line arguments. This can be overwritten in subclasses to add more arguments.

parseargs(parser, args=None)[source]

Use the parser returned by argparser() to parse the argument sequence args, modify self accordingly and return the result of the parsers parse_args() call.

service(args=None)[source]

Handle command line arguments and start or stop the daemon accordingly.

args must be a list of command line arguments (including the program name in args[0]). If args is None or unspecified sys.argv is used.

The return value is true when a starting option has been specified as the command line argument, i.e. if the daemon should be started.

The argparse arguments are available afterwards as self.args.