Note that there are some explanatory texts on larger screens.

plurals
  1. POPython daemon will not run in the background on Ubuntu
    primarykey
    data
    text
    <p>My Python daemon runs fine in the foreground of my Ubuntu system using this command in the terminal:</p> <pre><code>python /opt/my-daemon.py foreground </code></pre> <p>However when I try to call the daemon using the <strong>"start"</strong> command it fails, why?</p> <pre><code>python /opt/my-daemon.py start </code></pre> <p>This is how I call the command in the <code>/etc/rc.local</code> file:</p> <pre><code>python /opt/my-daemon.py start &amp; </code></pre> <p>Herewith the code:</p> <p><strong>1.daemon.py</strong></p> <pre><code>#!/usr/bin/env python import sys, os, time, atexit from signal import SIGTERM class Daemon: """ A generic daemon class. Usage: subclass the Daemon class and override the run() method """ def __init__(self, pidfile, stdin='/dev/null',stdout='/dev/null',stderr='/dev/null'): self.stdin = stdin self.stdout = stdout self.stderr = stderr self.pidfile = pidfile def daemonize(self): """ Do the UNIX double-fork magic. See Richard Stevens' "Advanced Programming in the UNIX Environment" for details (ISBN 0201563177) http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16 """ try: pid = os.fork() if pid &gt; 0: # exit first parent sys.exit(0) except OSError, e: sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror)) sys.exit(1) # Decouple from parent environment os.chdir("/") os.setsid() os.umask(0) # Do second fork try: pid = os.fork() if pid &gt; 0: # Exit from second parent sys.exit(0) except OSError, e: sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror)) sys.exit(1) # Redirect standard file descriptors sys.stdout.flush() sys.stderr.flush() si = file(self.stdin, 'r') so = file(self.stdout, 'a+') se = file(self.stderr, 'a+', 0) os.dup2(si.fileno(), sys.stdin.fileno()) os.dup2(so.fileno(), sys.stdout.fileno()) os.dup2(se.fileno(), sys.stderr.fileno()) # Write pidfile atexit.register(self.delpid) pid = str(os.getpid()) file(self.pidfile,'w+').write("%s\n" % pid) def delpid(self): os.remove(self.pidfile) def start(self): """ Start the daemon """ # Check for a pidfile to see if the daemon already runs try: pf = file(self.pidfile,'r') pid = int(pf.read().strip()) pf.close() except IOError: pid = None if pid: message = "pidfile %s already exist. Daemon already running?\n" sys.stderr.write(message % self.pidfile) sys.exit(1) # Start the daemon self.daemonize() self.run() def stop(self): """ Stop the daemon """ # Get the pid from the pidfile try: pf = file(self.pidfile,'r') pid = int(pf.read().strip()) pf.close() except IOError: pid = None if not pid: message = "pidfile %s does not exist. Daemon not running?\n" sys.stderr.write(message % self.pidfile) return # not an error in a restart # Try killing the daemon process try: while 1: os.kill(pid, SIGTERM) time.sleep(0.1) except OSError, err: err = str(err) if err.find("No such process") &gt; 0: if os.path.exists(self.pidfile): os.remove(self.pidfile) else: print str(err) sys.exit(1) def restart(self): """ Restart the daemon """ self.stop() self.start() def run(self): """ You should override this method when you subclass Daemon. It will be called after the process has been daemonized by start() or restart(). """ </code></pre> <p><strong>2.my-daemon.py</strong></p> <pre><code>import sys, time from daemon import Daemon import MySQLdb #MySQL libraries #Database parameters config = {"host":"localhost",...} try: conn = MySQLdb.connect(config['host'],... class MyDaemon(Daemon): def run(self): while True: time.sleep(2) #{Do processes, connect to the database, etc....} ... if __name__ == "__main__": daemon = MyDaemon('/tmp/daemon-example.pid') if len(sys.argv) == 2: if 'start' == sys.argv[1]: daemon.start() elif 'stop' == sys.argv[1]: daemon.stop() elif 'restart' == sys.argv[1]: daemon.restart() elif 'foreground' == sys.argv[1]: #This runs the daemon in the foreground daemon.run() else: print "Unknown command" sys.exit(2) sys.exit(0) else: print "usage: %s start|foreground|stop|restart" % sys.argv[0] sys.exit(2) </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload