Introduction
python-daemon implements the Unix daemon. Reference: PEP 3143
This library implements the Good Behaviour Daemon Specification of PEP 3143 "Standard Daemon Library".
The DaemonContext instance holds the program's behavior and the configured process environment.
Quick start
import time with daemon.DaemonContext(): f = open("/tmp/test.log",'w') while True: f.write(''' Library to implement a well-behaved Unix daemon process. This library implements the well-behaved daemon specification of PEP 3143, “Standard daemon process library”. A well-behaved Unix daemon process is tricky to get right, but the required steps are much the same for every daemon program. A DaemonContext instance holds the behaviour and configured process environment for the program; use the instance as a context manager to enter a daemon state. ''') f.write("{0}\n".format(time.ctime(time.time()))) time.sleep(1)
implement:
$ python3 daemon1.py $ tail -f /tmp/test.log This library implements the well-behaved daemon specification of PEP 3143, “Standard daemon process library”. A well-behaved Unix daemon process is tricky to get right, but the required steps are much the same for every daemon program. A DaemonContext instance holds the behaviour and configured process environment for the program; use the instance as a context manager to enter a daemon state. Thu Feb 8 14:21:43 2018 $ ps afx | grep -i daemon1 8646 pts/2 S+ 0:00 | \_ grep --color=auto -i daemon1 8640 ? S 0:00 \_ python3 daemon1.py $ kill -9 8640
To stop the above process, you can find the process number through ps, and then kill.
Note that the above code does not have any problems in python2, but in python you need to modify the way the library file runner.py opens the file.
# vi /usr/local/lib/python3.5/dist-packages/daemon/runner.py # 118 -120 self.daemon_context = DaemonContext() self.daemon_context.stdin = open(app.stdin_path, 'wb+',buffering=0) self.daemon_context.stdout = open(app.stdout_path, 'wb+',buffering=0) self.daemon_context.stderr = open( app.stderr_path, 'wb+', buffering=0)
more practical example
import time import logging import logging.handlers from daemon import runner class App(): def __init__(self): self.stdin_path = '/dev/null' self.stdout_path = '/dev/tty' self.stderr_path = '/dev/tty' self.pidfile_path = '/tmp/foo.pid' self.pidfile_timeout = 5 def run(self): logs = logging.getLogger('MyLogger') logs.setLevel(logging.DEBUG) fh = logging.handlers.RotatingFileHandler( '/tmp/test.log',maxBytes=10000000,backupCount=5) fh.setLevel(logging.DEBUG) formatter = logging.Formatter(u'%(asctime)s [%(levelname)s] %(message)s') fh.setFormatter(formatter) logs.addHandler(fh) while True: for i in range(10): logs.info("Beginning Scan {0}! \n".format(i)) time.sleep(1) app = App() daemon_runner = runner.DaemonRunner(app) daemon_runner.do_action()
implement:
$ python2 daemon2.py usage: daemon2.py start|stop|restart $ python3 daemon2.py start andrew@andrew-MS-7A71:~/code/python-chinese-library/libraries/daemon$ andrew@andrew-MS-7A71:~/code/python-chinese-library/libraries/daemon$ Traceback (most recent call last): File "/usr/local/lib/python3.5/dist-packages/lockfile/pidlockfile.py", line 77, in acquire write_pid_to_pidfile(self.path) File "/usr/local/lib/python3.5/dist-packages/lockfile/pidlockfile.py", line 161, in write_pid_to_pidfile pidfile_fd = os.open(pidfile_path, open_flags, open_mode) FileExistsError: [Errno 17] File exists: '/tmp/foo.pid' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "daemon2.py", line 39, in <module> daemon_runner.do_action() File "/usr/local/lib/python3.5/dist-packages/daemon/runner.py", line 274, in do_action func(self) File "/usr/local/lib/python3.5/dist-packages/daemon/runner.py", line 182, in _start self.daemon_context.open() File "/usr/local/lib/python3.5/dist-packages/daemon/daemon.py", line 389, in open self.pidfile.__enter__() File "/usr/local/lib/python3.5/dist-packages/lockfile/__init__.py", line 197, in __enter__ self.acquire() File "/usr/local/lib/python3.5/dist-packages/daemon/pidfile.py", line 60, in acquire super(TimeoutPIDLockFile, self).acquire(timeout, *args, **kwargs) File "/usr/local/lib/python3.5/dist-packages/lockfile/pidlockfile.py", line 85, in acquire self.path) lockfile.LockTimeout: Timeout waiting to acquire lock for /tmp/foo.pid andrew@andrew-MS-7A71:~/code/python-chinese-library/libraries/daemon$ python3 daemon2.py stop Terminating on signal 15 andrew@andrew-MS-7A71:~/code/python-chinese-library/libraries/daemon$ python3 daemon2.py stop Traceback (most recent call last): File "daemon2.py", line 39, in <module> daemon_runner.do_action() File "/usr/local/lib/python3.5/dist-packages/daemon/runner.py", line 274, in do_action func(self) File "/usr/local/lib/python3.5/dist-packages/daemon/runner.py", line 224, in _stop raise error daemon.runner.DaemonRunnerStopFailureError: PID file '/tmp/foo.pid' not locked
Note that the above error is caused by the process not existing when starting or stopping repeatedly.
References
The code address of this article: http://t.cn/R8scWAe
The address of the latest version of this article: http://t.cn/R8sVaXg
Communication QQ group: python test development 144081101
wechat : pythontesting
Taobao Tmall can send the link to qq850766020, generate coupons for you, and reduce your shopping costs!
Come and collect Alipay New Year's red envelopes! From January 1st, there is also a chance to get an additional exclusive red envelope! Copy this message and open the latest version of Alipay to get it! 2C56CV70sA
daemonize demo cannot run
https://pypi.python.org/pypi/python-daemon
An old-fashioned way of writing background processes
import time import logging import logging.handlers logs = logging.getLogger('MyLogger') logs.setLevel(logging.DEBUG) fh = logging.handlers.RotatingFileHandler( '/tmp/test.log',maxBytes=10000000,backupCount=5) fh.setLevel(logging.DEBUG) formatter = logging.Formatter(u'%(asctime)s [%(levelname)s] %(message)s') fh.setFormatter(formatter) logs.addHandler(fh) while True: for i in range(10): logs.info("Beginning Scan {0}! \n".format(i)) time.sleep(1)
This does not execute in the background, but you can use linux's nohup and &. Adding the following start and stop scripts for this is actually not a hassle:
See the shell script: http://t.cn/R8scWAe
$ sh startup.sh ================================================================================================================ Starting older.py(PID=15315)...[Success] ================================================================================================================ $ sh startup.sh ================================================================================================================ older.py already started(PID=15315) ================================================================================================================ $ sh shutdown.sh ================================================================================================================ Stopping older.py(PID=15315)...[Success] ================================================================================================================ $ sh shutdown.sh ================================================================================================================ older.py is not running ================================================================================================================
other
Supervisord can control linux processes from linux, and of course it can be backgrounded.
How do you create a daemon in Python?
You can also register as a background process with linux systemd.