Cron is a simple UNIX utility that manages and schedules the execution of commands in your computer. It was first developed in 1987 by Paul Vixie and it has since become an invaluable tool in Linux-based operating systems for both administrators and users alike.
Nowadays, there are a number of cron implementations and rewrites that you can easily install in your Linux system. Despite the differences, these programs all share the same Vixie Cron lineage.
As such, this article aims to provide a basic overview of how the original Vixie cron works, its syntax, and how you can use it to schedule tasks in your Linux system.
Also read: How to Easily Create Cron jobs in Linux with Zeit
How Does Cron Work?
Cron is an incredibly simple UNIX utility. It works in two parts. Cron first runs as a background process that starts when you first boot up your system.
From there, it then reads a specific file every minute. This file contains a list of commands which, in turn, consists of a time code and a file path for each script or program that you want to run.
This approach allows cron to be highly flexible in large systems. For example, modern cron implementations such as Cronie only runs a single instance of cron even if that machine hosts multiple users.
Cronie makes this possible by providing local crontabs for each user installed in the system. As such, cron only needs to know who owns the crontab, that user’s permission level and the commands inside the crontab.
This not only makes the system more efficient but also more secure by reducing the amount of privileged programs running in memory.
Crontab: The Heart of Cron
Every cron implementation uses some form of a crontab. This is a simple text file that contains all of the commands that cron will run for that particular user. As described above, each user in the system has their own crontab. They can view by running the following command:
crontab -l
This will print the contents of the current user’s crontab to standard output. This can be incredibly helpful if you just want to quickly see what commands cron is running for that user.
In order to edit it, you will need to run the command:
crontab -e
This will tell cron to run your default text editor and load the crontab file inside it. Doing that will allow you to edit the crontab file.
Also read: How to Use Systemd Timers as a Cron Replacement
The Crontab Syntax
The syntax of the crontab file is incredibly simple. A single line in this file will indicate a corresponding command that needs to be run for that particular user. The general form of a crontab command looks something like this:
m h d mon dow [flags] command
The time-interval is a field of five digits where you can tell cron how often you want to run a command. This is the core feature of any cron implementation and it allows you to be both specific and flexible with how cron treats recurring tasks.
- m = minute between 0 and 59
- h = hour between 0 and 23
- d = day of the month between 1 and 31
- mon = month between 1 and 12
- dow = day of the week between 0 and 6. Zero is Sunday.
The flags
field is a set of options that modify how cron behaves for a single command. For example, you can include the -n
option to stop cron from sending system mail.
The command
field is the command cron will run at set intervals. This can either be a shell script that you wrote or a program path with flags.
Knowing that, you can use all of these together in a single crontab line to create specific time intervals for your tasks. For example, I can run a script on my Ubuntu system every July 24th on 2:30 AM by writing the following crontab line:
30 2 24 7 * /home/$USER/myscript.sh
Note: It is recommended to run a cronjob at “uncommon” number of minutes (11, 27 34, etc) to avoid having different cron jobs overlap with each other.
Short codes
Crontab allows you to use some short codes to make your cron entries easier to read.
@reboot
– Run once, at startup@yearly
– Run once a year, “0 0 1 1 *”.</>@annually
– same as @yearly@monthly
– Run once a month, “0 0 1 * *”@weekly
– Run once a week, “0 0 * * 0”@daily
– Run once a day, “0 0 * * *”@midnight
– same as @daily@hourly
– Run once an hour, “0 * * * *”
For example:
@daily ramces /home/ramces/.scripts/file-backup.sh
The @reboot
shortcode allows you to create scripts to run at startup:
@reboot /home/ramces/.scripts/bootup.sh
This can be incredibly helpful if you want to create a way of ensuring that commands are run as soon as you turn on the machine.
Note: Depending on your system setup, the @reboot
shortcode may or may not work as intended in your system.
System Crontabs
Another brilliant feature of cron is that it can manage recurring system-wide tasks as you can also create root crontab files. This can be incredibly helpful if you want to automate system maintenance and updates.
To create a root crontab, you just have to use sudo
with the command, or login to your root account:
sudo crontab -e
The system crontab largely follows the same format as the user’s crontab. However, one key difference between the two is that the root crontab allows you to run commands as any user in the system:
m h d mon dow user [flags] "command"
Knowing that, you can then use this to create both user and root-level recurring commands within the same crontab:
30 2 * * sun root /bin/apt update 30 5 * * * ramces /home/ramces/.scripts/file-backup.sh
Doing it this way allows me to preserve the permissions of my files while also having a single place where I can edit the commands that I want to run.
Also read: Why and How to Edit Your Sudoers File in Linux
Editing cron entries as another user
If instead of editing the crontab as a root user, you want to schedule cron job as another user, it is also possible with the -u
flag.
sudo crontab -u username -e
For example, to run a cron job as the “www-data” user, use the following command:
sudo crontab -u www-data -e
Also read: How to Save the Terminal Output to a File in Linux
Reviewing cron activity
Although you are now set to run specific commands or scripts, you may want to ensure it ran. Built into cron is that once a command is run, it will email the cron owner. This can be changed with the “MAILTO” variable.
Adding MAILTO=youremail@yourdomain.com
will send all cron job reports to a specified email. This variable can typically be found at the very top of the crontab edit screen. However, if it is not there, you can add the variable, and it will work as expected.
Multiple email addresses can be separated with a comma. If you need a different command emailed elsewhere, you can add the MAILTO command directly above the command. Commands after that mailto will be emailed to the new address. If you leave MAILTO=
blank, the notifications will be sent to the owner of the cron entry.
If you don’t want to receive any email, you can also check the cron logs. On most systems, accessing the cron logs will require superuser permissions. The cron log can be found under “/var/log.” The cron or syslog file will display the log of executed cron entries.
sudo grep crontab syslog
Frequently Asked Questions
Why is my cron command running every minute instead of once an hour?
This is one of the most common pitfalls when managing crontabs. By default, adding an asterisk value in a time code means that it will run for every instance possible for that value. For example, a value of 0 12 * * *
will tell cron that you want to run a command once a day by 12:00 PM.
However, most beginners often write the same time code as * 12 * * *
. Writing it this way will mean that the command will run once a minute from 12:00 PM to 12:59 PM. As such, it is good practice to write 0 in the minute field to make sure that the command only runs once.
Are there any other options that I can use with cron?
Aside from -n
and MAILTO
variables, you can also use the -s
command to tell the program to be strict with running commands. Using this option will force cron to only focus on the current command until it finishes. This can be incredibly helpful if your machine uses a set of commands that needs to run in a specific order.
You can also use the SHELL
variable to get cron to use a different shell for its commands. For example: SHELL=/bin/ksh
Image credit: Unsplash
Our latest tutorials delivered straight to your inbox