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("Daemon started with pid {}\n".format(os.getpid())) sys.stdout.write("Daemon stdout output\n") sys.stderr.write("Daemon stderr output\n") c = 0 while True: sys.stdout.write('{}: {}\n'.format(c, time.ctime(time.time()))) sys.stdout.flush() c += 1 time.sleep(1)
class Daemon
(object
):
The Daemon
class provides methods for starting and stopping a
daemon process as well as handling command line arguments.
def __init__
(self
, stdin
='/dev/null'
, stdout
='/dev/null'
, stderr
='/dev/null'
, pidfile
=None
, user
=None
, group
=None
):
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.
def openstreams
(self
):
Open the standard file descriptors stdin, stdout and stderr as specified in the constructor.
def handlesighup
(self
, signum
, frame
):
Handle a SIG_HUP
signal: Reopen standard file descriptors.
def handlesigterm
(self
, signum
, frame
):
Handle a SIG_TERM
signal: Remove the pid file and exit.
def switchuser
(self
, user
, group
):
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).
def start
(self
):
Daemonize the running script. When this method returns the process is completely decoupled from the parent environment.
def stop
(self
):
Send a SIGTERM
signal to a running daemon. The pid of the daemon
will be read from the pidfile specified in the constructor.
def argparser
(self
):
Return an argparse
parser for parsing the command line arguments.
This can be overwritten in subclasses to add more arguments.
def parseargs
(self
, parser
, args
=None
):
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.
def service
(self
, args
=None
):
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
.