Last active
May 8, 2021 09:31
-
-
Save leafsummer/245d95ae5d5e431c0af8 to your computer and use it in GitHub Desktop.
daemonize a process class of python script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import sys | |
import time | |
import atexit | |
class Daemon(object): | |
def __init__(self, pidfile="/dev/null", stdin="/dev/null", stdout="/dev/null", stderr="/dev/null"): | |
self.stdin = stdin | |
self.stdout = stdout | |
self.stderr = stderr | |
self.pidfile = pidfile | |
def _daemonize(self): | |
try: | |
# the first fork to leave the parent process | |
pid = os.fork() | |
if pid > 0: | |
sys.exit(0) | |
except OSError, e: | |
sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror)) | |
sys.exit(1) | |
# leave the term | |
os.setsid() | |
os.chdir("/") | |
# set file permission | |
os.umask(0) | |
try: | |
# the second fork to forbid opening the term | |
pid = os.fork() | |
if pid > 0: | |
sys.exit(0) | |
except OSError, e: | |
sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror)) | |
sys.exit(1) | |
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()) | |
atexit.register(self.delpid) | |
pid = str(os.getpid()) | |
f = file(self.pidfile,'w') | |
f.write("%s\n" % pid) | |
f.close() | |
self.pid = pid | |
def delpid(self): | |
os.remove(self.pidfile) | |
def start(self): | |
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) | |
try: | |
self._daemonize() | |
self._run() | |
except Exception, e: | |
print e | |
def stop(self): | |
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 | |
try: | |
while True: | |
os.kill(pid, signal.SIGTERM) | |
time.sleep(1) | |
except OSError, err: | |
err = str(err) | |
if err.find("No such process") > 0: | |
if os.path.exists(self.pidfile): | |
os.remove(self.pidfile) | |
else: | |
print str(err) | |
sys.exit(1) | |
def restart(self): | |
self.stop() | |
self.start() | |
def _run(self): | |
""" | |
you must inherit to implement this function | |
""" | |
print "I'm Daemon Parent Class!" | |
class TestDaemon(Daemon): | |
def _run(self): | |
while True: | |
test_file = file("/tmp/test_file.log",'a+') | |
test_file.write("Test Daemon ok! time:" + str(time.time()) + " Pid:" + str(os.getpid()) + "\n") | |
test_file.close() | |
time.sleep(1) | |
if __name__ == "__main__": | |
daemon = TestDaemon("/tmp/test.pid") | |
daemon.start() | |
time.sleep(10) | |
daemon.stop() | |
daemon.restart() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment