3

I read How do you create a daemon in Python? and also this topic, and tried to write a very simple daemon :

import daemon
import time
with daemon.DaemonContext():
    while True:
        with open('a.txt', 'a') as f:
            f.write('Hi')
        time.sleep(2)

Doing python script.py works and returns immediately to terminal (that's the expected behaviour). But a.txt is never written and I don't get any error message. What's wrong with this simple daemon?

Community
  • 1
  • 1
Basj
  • 41,386
  • 99
  • 383
  • 673

3 Answers3

2

daemon.DaemonContext() has option working_directory that has default fault value / i.e. your program probably doesn't have permission to create a new file there.

J.J. Hakala
  • 6,136
  • 6
  • 27
  • 61
0

One thing that's wrong with it, is it has no way to tell you what's wrong with it :-)

A daemon process is, by definition, detached from the parent process and from any controlling terminal. So if it's got something to say – such as error messages – it will need to arrange that before becoming a daemon.

From the python-daemon FAQ document:

Why does the output stop after opening the daemon context?

The specified behaviour in PEP 3143_ includes the requirement to detach the process from the controlling terminal (to allow the process to continue to run as a daemon), and to close all file descriptors not known to be safe once detached (to ensure any files that continue to be used are under the control of the daemon process).

If you want the process to generate output via the system streams ‘sys.stdout’ and ‘sys.stderr’, set the ‘DaemonContext’'s ‘stdout’ and/or ‘stderr’ options to a file-like object (e.g. the ‘stream’ attribute of a ‘logging.Handler’ instance). If these objects have file descriptors, they will be preserved when the daemon context opens.

Set up a working channel of communication, such as a log file. Ensure the files you open aren't closed along with everything else, using the files_preserve option. Then log any errors to that channel.

bignose
  • 30,281
  • 14
  • 77
  • 110
-1

The problem described here is solved by J.J. Hakala's answer.

Two additional (important) things :

  • Sander's code (mentioned here) is better than python-daemon. It is more reliable. Just one example: try to start two times the same daemon with python-daemon : big ugly error. With Sander's code : a nice notice "Daemon already running."

  • For those who want to use python-daemon anyway: DaemonContext() only makes a daemon. DaemonRunner() makes a daemon + control tool, allowing to do python script.py start or stop, etc.

Community
  • 1
  • 1
Basj
  • 41,386
  • 99
  • 383
  • 673