So far, we've explored how to run our own processes. However, computer operating systems also have many of their own processes in the background, silently running and making sure everything works "as you'd expect it to". Lets learn a little bit more about these processes, called daemons (pronounced day-mon, or alternatively, to rhyme with diamond)
Note: This section will be somewhat less interactive with daemons, for a few reasons:
1. Cornell IT won't allow you to make changes to daemons on their server unless you're high-level support
2. Linux and MacOS differ significantly on how daemons are managed. Linux uses the service
command, whereas MacOS uses launchctl
If you wish to further your education in an interactive manner, I'd recommend looking into these
What is a Daemon?
In Linux, there are three types of processes; interactive, batch, and daemon:
- Interactive processes are the ones that you're most familiar with. They are associated with a terminal, and you can interact with them (such as sending them signals)
- Batch processes are less common. They are not associated with a terminal, but are groups of tasks from a list submitted to a process queue. They are best suited for performing recurring operations when system usage is low - think monthly system backups
This leaves daemons. Daemon processes run in the background, and are spawned (term for creating a process) right after a system boots. Specifically, they are spawned from the init
process by forking it, something we explored in Chapter 9. In this way, orphans and daemons are somewhat similar in that their parent is the init
process; creating an orphan is one way of making your own pseudo-daemon.
Examples of Daemons
In Linux, it is specified that the names of daemon processes end with "d". Using ps
and/or htop
(especially when listing processes as a tree with htop -t
or htop --tree
), you might be able to catch some daemons yourself. Here are some common examples:
systemd
: A system and service manager. On modern systems, this will be theinit
process and have a PID of 1 (including on our server)logind
: Manages user login and seatssshd
: Manages all SSH connections. This is what handles your request to connect to the C2S2 and ECELinux servers, as well as the connection while you're activehttpd
: The HTTP service manager, usually run on web serversftpd
: The FTP (File Transfer Protocol) service manager. FTP is used to transfer files between one computer and another using the TCP protocolcrond
: A scheduling daemon, used for scheduling tasks. This is commonly used by users to schedule their own tasks - we'll explore this in a bit!
If you're curious about what daemons are currently running on a system, one way to view them is to use the service
command. service
is used to manage daemons, and running service --status-all
will show you the status of all currently running daemons.
Case Study: cron
Background
One of the more popular daemons to use is cron
. cron
is lightweight daemon used to schedule processes, and can be used by users to run processes regularly, even when they're not logged in. While many newer users have opted to use systemd
itself to schedule their processes, cron
is what started it all.
To use cron
, we must first use a crontab
. We can create one with the command
crontab -e
This command edits your existing crontab if it exists, and creates one if not.
Note that the above command will use the default text editor for your system. This is stored in the EDITOR
environment variable; if you wish to use something other than the default (ex. nano
on the C2S2 server), you will have to modify this variable. Examples include code
(for VSCode), emacs
, or vim
Crontab Formatting - Time
Crontabs require a specific syntax for specifying a command and when it should be run. Specifically, they follow the following syntax:
* * * * * <command to be executed> – – – – – | | | | | | | | | `—– day of week (0 – 6) (Sunday=0) | | | `——- month (1 – 12) | | `——— day of month (1 – 31) | `———– hour (0 – 23) `————- min (0 – 59)
Here, we can see how we can specify when a command should be run simply by specifying the minutes, hours, days, months, and days of week (if necessary) when it should be run. For example, 0 0 1 1 * <command>
will run the command every January 1st at midnight.
In addition to this, there are a few more characters that Crontabs use:
*
is a wildcard, and can stand for anything. For example,* * 1 * * <command>
will run the command on the first of every month-
specify a range. For example,0 0 * * 1-5 <command>
will run the command at midnight on every weekday/
is used for time intervals. For example,*/10 * * * * <command>
will run the command every 10 minutes.
These can all be combined as well. For example, 0-30/5 12 * * * <command>
will run the command during the first half of the 12 p.m. hour every 5 minutes.
Finally, some patterns are so common that Crontabs have specific keywords for them. These are:
Keyword | Meaning |
---|---|
@reboot | Run once, at system startup |
@yearly | Run once every year, same as 0 0 1 1 * |
@annually | (same as @yearly) |
@monthly | Run once every month, same as 0 0 1 * * |
@weekly | Run once every week, same as 0 0 * * 0 |
@daily | Run once each day, same as 0 0 * * * |
@midnight | (same as @daily) |
@hourly | Run once an hour, same as 0 * * * * |
For example, @hourly <command>
will run the command once every hour.
If you ever get confused what a particular crontab pattern means, I recommend using Crontab Guru to help understand it
Crontab Formatting - Commands
The other element of a Crontab entry is the command. This will be the same as any normal command you might run from a terminal (under the hood, cron
uses the default shell located at /bin/sh
to run the commands. For C2S2, this is Bash). HOWEVER, you must remember that cron
isn't you! It may not have the same notion of which version of Python to use, and isn't guaranteed to start in any particular directory.
For example, suppose I have a Python file titled test.py
in my home folder. To run it from my terminal, one might simply do
python test.py
However, cron
may not know about the specific version of Python you want to use, and isn't guaranteed to start in the same directory. Therefore, we must specify absolute paths to everything we use. Modifying this command for a Crontab entry, it might look like:
/usr/bin/python /home/<netid>/test.py
Remember, if you're ever unsure about the location of a particular program that you use, you can use the which
command (ex. which python
)
Full cron
Example
Alright - let's put it all together! For this, in your home directory, you'll need a simply Python script that appends a line to a file. Save the following script as test.py
in your home/NetID folder:
file = open( "test.txt", "a" ) file.write( "Hi! This is cron saying hello :)\n" ) file.close()
This script should write a new line to a test.txt
file every time it's run.
Next, use crontab -e
to edit your Crontab. Insert the following entry to run this script every minute (replacing <netid>
with your NetID, such that the path points to the script we just made):
* * * * * /usr/bin/python /home/<netid>/test.py
Save the Crontab and...that's it! cron
should take care of running the script for you every minute. Wait a few minutes, and come back - you should have a test.txt
file waiting for you with a few entries! When you're satisfied, you can delete this entry from the Crontab to avoid cron
scheduling it (as well as delete your Crontab with crontab -r
, if you wish)
If cron
faces an error, or gets some output from your commands, it doesn't throw an error by default. However, you can make it aware of your email address to send any such errors/output to you - see here
For more information on cron
, this cheatsheet is very helpful
Addendum: Why "daemon"?
Many have gotten confused over the name "daemon" - what does it actually mean? I certainly don't know enough about it , so I figured I'd rather quote this good article on them:
"The earliest form of the word, daemon, was spelled as daimon, a form of guardian angel – attendant spirits that helped form the character of people they assisted. Socrates claimed to have one that served him in a limited way, but correctly. Socrates’ daimon only told him when to keep his mouth shut. Socrates described his daimon during his trial in 399 BC, so the belief in daimons has been around for quite some time. Sometimes, the spelling of daimon is shown as daemon. Daimon and daemon, here, mean the same thing.
While a daemon is an attendant, a demon is an evil character from the Bible. The differences in spelling is intentional and was apparently decided upon in the 16th century. Daemons are the good guys, and demons are the bad ones.
The use of the word, daemon, in computing came about in 1963. Project MAC is shorthand for Project on Mathematics and Computation, and was created at the Massachusetts Institute of Technology. It was here that the word, daemon, came into common use to mean any system process that monitors other tasks and performs predetermined actions depending on their behavior, The word, daemon was named for Maxwell’s daemon.
Maxwell’s daemon is the result of a thought experiment. In 1871, James Clerk Maxwell imagined an intelligent and resourceful being that was able to observe and direct the travel of individual molecules in a specific direction. The purpose of the thought exercise was to show the possibility of contradicting the second law of thermodynamics"