Beginners Guide to Scheduling Periodic Tasks in Linux using Cron
Performing Periodic Tasks
Often, people find that they are (or ought to be) performing tasks on a regular basis. In system administration, such tasks might include removing old, unused files from the /tmp directory, or checking to make sure a file that’s collecting log messages hasn’t grown too large. Other users might find their own tasks, such as checking for large files that they aren’t using anymore or checking a website to see if anything new has been posted.
The cron service allows users to configure commands to be run on a regular basis, such as every 10 minutes, once every Thursday, or twice a month. Users specify what commands should be run at what times by using the crontab command to configure their “cron table”. The tasks are managed by a traditional Linux (and Unix) daemon, the crond daemon.
The cron Service
The crond daemon is the daemon that performs periodic tasks on behalf of the system or individual users. Usually, the daemon is started as the system boots, so most users can take it for granted. By listing all processes and searching for crond, you can confirm that the crond daemon is running.
$ ps aux | grep crond
root 891 0.0 0.0 1572 128 ? S Jun17 0:00 crond
hogan 8118 0.0 0.2 3576 644 pts/2 S 10:15 0:00 grep crond
If the crond daemon is not running, your system administrator would need to start the crond service as root.
crontab Syntax
Users specify which jobs to run, and when to run them, by configuring a file known as the “cron table”, more often abbreviated “crontab”. An example crontab file is listed below.
# set the default language to be english
LOCALE=en_US
05 * * * * procinfo
15 04 * * * find $HOME -size +100k
25 04 1 * * echo "Pay your bills"
35 04 14 3 * echo "Beware the Ides of March" | mail -s "a warning" julius
45 04 * * 1 find $HOME -atime +30 | lpr
A crontab file is a line based configuration file, with each line performing one of three functions:
- Comments: All lines who first (non-space) character is a # are considered comments, and are ignored.
- Environment variables: All lines that have the form name = value are used to define environment variables.
- Cron commands: Any other (non blank) line is considered a cron command, which is made up of six fields described below.
Cron command lines consist of six whitespace-separated fields. The first 5 fields are used to specify when to run the command, and the remaining sixth field (composed of everything after the fifth field) specifies the command to run. The first five fields specify the following information:
Each of the first five fields must be filled with a token using the following syntax:
token | meaning | example | interpretation (if used in the first field) |
---|---|---|---|
* | every time | * | every minute |
n | at the specified time | 10 | every hour at 10 minutes past the hour |
n, n, … | at any of the specified times | 22,52 | every hour at 22 and 52 minutes past the hour |
*/n | every nth time | */15 | every 15 minutes (at 0, 15, 30 and 45 minutes past the hour) |
Using the crontab Command
Users seldom manage their crontab file directly (or even know where it is stored), but instead use the crontab command to edit, list, or remove it.
$ crontab {-e | -l | -r}
$ crontab FILE
Edit, list, or remove the current crontab file, or replace the current crontab file with FILE.
Switch | Effect |
---|---|
-e | edit current file |
-l | list current file |
-r | remove current file |
In the following sequence of commands, hogan will use the crontab command to manage his crontab configuration. He first lists his current crontab configuration to the screen, then he lists the current file again, storing the output into the file mycopy.
$ crontab -l
05 * * * * procinfo
15 04 * * * find $HOME -size +100k
25 04 1 * * echo "Pay your bills"
35 04 14 3 * echo "Beware the Ides of March" | mail -s "a warning" julius
45 04 * * 1 find $HOME -atime +30 | lpr
$ crontab -l > mycopy
Next, hogan removes his current crontab configuration. When he next tries to list the configuration, he is informed that no current configuration exists.
$ crontab -r
$ crontab -l
no crontab for hogan
In order to restore his cron configuration, hogan uses the crontab command once again, this time specifying the mycopy file as an argument. Upon listing his configuration again, he finds that his current configuration was read from the mycopy file.
A little annoyingly, the banner has been duplicated in the process. Can you out why?
$ crontab mycopy
$ crontab -l
05 * * * * procinfo
15 04 * * * find $HOME -size +100k
25 04 1 * * echo "Pay your bills"
35 04 14 3 * echo "Beware the Ides of March" | mail -s "a warning" julius
45 04 * * 1 find $HOME -atime +30 | lpr
$ rm mycopy
Editing crontab Files in Place
Often, users edit their crontab files in place, using crontab -e. The crontab command will open the current crontab configuration into the user’s default editor. When the user has finished editing the file, and exits the editor, the modified contents of the file are installed as the new crontab configuration.
The default editor is /bin/vi, however, crontab, like many other commands, examines the EDITOR environment variable. If the variable has been set, it will be used to specify which editor to open. For example, if hogan prefers to use the nano editor, he can first set up the EDITOR environment variable to /usr/bin/nano (or simply nano), and then run crontab -e.
If hogan wanted to use nano as his editor, he could use one of the following approaches:
$ export EDITOR=nano
$ crontab -e
or
$ EDITOR=nano crontab -e
or, even better, hogan could add the line “export EDITOR=nano” to his .bash_profile file, and the environment variable would be set automatically every time he logged in. In summary, there are two ways someone could go about creating or modifying their crontab configuration.
1. Create a text file containing their desired configuration, and then install it with crontab FILENAME. 2. Edit their configuration in place with crontab -e.
Where does the output go?
How does the user receive output from commands run by cron? The crond daemon will mail stdout and stderr from any commands run to the local user. Suppose ventura had set up the following cron job:
05 * * * * cal
Once an hour, at five minutes past the hour, he could expect to receive new mail that looks like the following:
November 2020
Su Mo Tu We Th Fr Sa
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
The mail message contains the output of the command in the body and all defined environment variables in the message headers. Optionally, ventura could have set the special MAILTO environment variable to a destination email address, and mail would be sent to that address instead:
[email protected]
05 * * * * cal
Environment Variables and cron
When configuring cron jobs, users should be aware of subtle detail. When the crond daemon starts the user’s command, it does not run the command from a shell, but instead forks and execs the command directly. This has an important implication: Any environment variables or aliases that are configured by the shell at startup, such as any defined in /etc/profile or ~/.bash_profile, will not be available when cron executes the command.
If a user wants an environment variable to be defined, they need to explicitly define the variable in their crontab configuration.