If you are an average internet user, then you interact with daemons every day. This article will describe what daemons do, how to create them in Python, and what you can use them for.
A daemon is a process on UNIX that runs in the background and will typically keep running until it is explicitly told to stop. Examples of daemon processes include web servers (lighttpd and Apache httpd), schedulers (cron and at), DNS servers (bind), mail servers (courier and dovecot), and database servers (MySQL and PostgreSQL).
The typical web user will probably interact with at least one UNIX daemon in the form of a web server, DNS server, or database server on an average day. These types of processes run in the background on a server somewhere, unattended by any person, working tirelessly to do the work that they were designed for.
You can background a process on UNIX by putting an ampersand (&) at the end of the command that you started it with. For example:
dink:~ jmjones$ $(sleep 10; echo echo "WAKING UP";) & [1] 314 dink:~ jmjones$ WAKING UP
This backgrounded the sleep and echo commands. Ten seconds later, after sleep completed, the command echoed “WAKING UP” and appeared on my terminal. But just running a process in the background doesn’t qualify it for daemon status. There are some deeper technical qualifications that an aspiring process has to meet in order to be branded with the daemon label.
Following is the recipe “Forking a Daemon Process on Unix” from The Python Cookbook that will allow your Python code to daemonize itself.
import sys, os def daemonize (stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'): # Perform first fork. try: pid = os.fork( ) if pid > 0: sys.exit(0) # Exit first parent. except OSError, e: sys.stderr.write("fork #1 failed: (%d) %sn" % (e.errno, e.strerror)) sys.exit(1) # Decouple from parent environment. os.chdir("/") os.umask(0) os.setsid( ) # Perform second fork. try: pid = os.fork( ) if pid > 0: sys.exit(0) # Exit second parent. except OSError, e: sys.stderr.write("fork #2 failed: (%d) %sn" % (e.errno, e.strerror)) sys.exit(1) # The process is now daemonized, redirect standard file descriptors. for f in sys.stdout, sys.stderr: f.flush( ) si = file(stdin, 'r') so = file(stdout, 'a+') se = file(stderr, 'a+', 0) os.dup2(si.fileno( ), sys.stdin.fileno( )) os.dup2(so.fileno( ), sys.stdout.fileno( )) os.dup2(se.fileno( ), sys.stderr.fileno( ))
One way that a daemon process differs from a normal backgrounded task is that a daemon process disassociates from its calling process and controlling terminal. This recipe outlines the standard procedure for creating a daemon process. This procedure includes forking once, calling setsid to become a session leader, then forking a second time.
Along the way, it is common to also change directory to / to ensure that the resulting working directory will always exist. It also ensures that the daemon process doesn’t tie up the ability of the system to unmount the filesystem that it happens to be in. It is also typical to set its umask to 0 so that its file creation is set to the most permissive.
After becoming a daemon, this Python example also sets its standard input (stdin), standard output (stdout), and standard error (stderr) to the values the caller specified.
So, why would you want to cause your Python code to daemonize itself?
In general, if you have any code that you want to run for a long time in the background with no user interaction, it is a good candidate for daemonization. You may be wondering, “Why not just use the ampersand (&) like you showed a few examples back?” If you do that, you’re not totally guaranteed that logging out won’t kill that process.
As an example of daemon processes that you may find yourself in need of writing one day, I’ve written some system monitoring utilities that need to check different servers and processes on various intervals. I wanted these system monitoring utilities to run indefinitely in the background and they need no user interaction, so they were a good candidate to let them be daemonized. They are, in fact, running at this very moment monitoring some of my production systems.
Here is a small piece of code that uses the daemonize() function from the previous example.
#!/usr/bin/env python import daemonize import time import logging import os curr_dir = os.getcwd() logfile = os.path.join(curr_dir, 'test_daemon.log') logging.basicConfig(filename=logfile, level=logging.DEBUG, format="%(asctime)s [%(levelname)s] %(message)s") daemonize.daemonize() pid_fn = '/var/run/lighttpd.pid' logging.info('starting') logging.debug('current directory is %s' % os.getcwd()) while True: try: pidfile = open(pid_fn) pid = int(pidfile.read()) pidfile.close() logging.debug('got pid %s for %s' % (pid, pid_fn)) except IOError: logging.warn('IOError on pidfile open') time.sleep(60) continue except ValueError: logging.warn('ValueError on pidfile open') time.sleep(60) continue try: stat_fn = os.path.join('/proc', str(pid), 'status') logging.debug('opening file %s' % stat_fn) stat_file = open(stat_fn, 'r') for line in stat_file: line = line.strip() if line.startswith('VmRSS'): logging.info(line) break stat_file.close() time.sleep(60) except IOError: logging.warn('IOError on statfile open') time.sleep(60) continue
The purpose of this script is to log the memory usage of the lighttpd web server once every minute. This script tries to open the lighttpd pidfile (/var/run/lighttpd.pid) to see what process ID lighttpd has. Then, it opens /proc/{{pid}}/status, where {{pid}} is the process ID of the lighttpd process. (Files in /proc contain tons of system and process-specific information.)
The script then iterates over each line of the status file and logs the first line that starts with the text string “VmRSS”. The “VmRSS” line in the status file shows the amount of memory the process is actively using. The script keeps looping over these steps until it is explicitly killed or it hits an exception I didn’t plan for.
Here is some of the output from running the script:
2008-11-18 05:44:24,627 [INFO] starting 2008-11-18 05:44:24,628 [DEBUG] current directory is / 2008-11-18 05:44:24,631 [DEBUG] got pid 13291 for /var/run/lighttpd.pid 2008-11-18 05:44:24,631 [DEBUG] opening file /proc/13291/status 2008-11-18 05:44:24,631 [INFO] VmRSS:1924 kB 2008-11-18 05:45:24,631 [DEBUG] got pid 13291 for /var/run/lighttpd.pid 2008-11-18 05:45:24,632 [DEBUG] opening file /proc/13291/status 2008-11-18 05:45:24,632 [INFO] VmRSS:1924 kB
Notice that the current directory is “/”. The daemonize() function changed the script’s working directory there as part of the process. I only included two iterations of the loop, but you can see that it ran at 05:44:24, slept for 60 seconds, then ran again at 05:45:24.
Daemonizing a process is something you probably don’t need to do every day. But if you have a need to kick off a process and have it run indefinitely in the background, this approach could prove useful to you.
Also by Jeremy M. Jones:
Building Command Line Utilities with Python
This article was first published on EnterpriseITPlanet.com.
Huawei’s AI Update: Things Are Moving Faster Than We Think
FEATURE | By Rob Enderle,
December 04, 2020
Keeping Machine Learning Algorithms Honest in the ‘Ethics-First’ Era
ARTIFICIAL INTELLIGENCE | By Guest Author,
November 18, 2020
Key Trends in Chatbots and RPA
FEATURE | By Guest Author,
November 10, 2020
FEATURE | By Samuel Greengard,
November 05, 2020
ARTIFICIAL INTELLIGENCE | By Guest Author,
November 02, 2020
How Intel’s Work With Autonomous Cars Could Redefine General Purpose AI
ARTIFICIAL INTELLIGENCE | By Rob Enderle,
October 29, 2020
Dell Technologies World: Weaving Together Human And Machine Interaction For AI And Robotics
ARTIFICIAL INTELLIGENCE | By Rob Enderle,
October 23, 2020
The Super Moderator, or How IBM Project Debater Could Save Social Media
FEATURE | By Rob Enderle,
October 16, 2020
FEATURE | By Cynthia Harvey,
October 07, 2020
ARTIFICIAL INTELLIGENCE | By Guest Author,
October 05, 2020
CIOs Discuss the Promise of AI and Data Science
FEATURE | By Guest Author,
September 25, 2020
Microsoft Is Building An AI Product That Could Predict The Future
FEATURE | By Rob Enderle,
September 25, 2020
Top 10 Machine Learning Companies 2020
FEATURE | By Cynthia Harvey,
September 22, 2020
NVIDIA and ARM: Massively Changing The AI Landscape
ARTIFICIAL INTELLIGENCE | By Rob Enderle,
September 18, 2020
Continuous Intelligence: Expert Discussion [Video and Podcast]
ARTIFICIAL INTELLIGENCE | By James Maguire,
September 14, 2020
Artificial Intelligence: Governance and Ethics [Video]
ARTIFICIAL INTELLIGENCE | By James Maguire,
September 13, 2020
IBM Watson At The US Open: Showcasing The Power Of A Mature Enterprise-Class AI
FEATURE | By Rob Enderle,
September 11, 2020
Artificial Intelligence: Perception vs. Reality
FEATURE | By James Maguire,
September 09, 2020
Anticipating The Coming Wave Of AI Enhanced PCs
FEATURE | By Rob Enderle,
September 05, 2020
The Critical Nature Of IBM’s NLP (Natural Language Processing) Effort
ARTIFICIAL INTELLIGENCE | By Rob Enderle,
August 14, 2020
Datamation is the leading industry resource for B2B data professionals and technology buyers. Datamation's focus is on providing insight into the latest trends and innovation in AI, data security, big data, and more, along with in-depth product recommendations and comparisons. More than 1.7M users gain insight and guidance from Datamation every year.
Advertise with TechnologyAdvice on Datamation and our other data and technology-focused platforms.
Advertise with Us
Property of TechnologyAdvice.
© 2025 TechnologyAdvice. All Rights Reserved
Advertiser Disclosure: Some of the products that appear on this
site are from companies from which TechnologyAdvice receives
compensation. This compensation may impact how and where products
appear on this site including, for example, the order in which
they appear. TechnologyAdvice does not include all companies
or all types of products available in the marketplace.