cron is a commonly confusing and misconfigured aspect of the
The controlling files for cron are the cron-tables or crontabs. The crontabs are often located in
Unlike other
The
At first, that might sound a little annoying. However, let’s take a look at the
process of “adding” a job. To add a cron job, you must first list out
the contents of the existing crontab with the -l option. If you are root and
wish to add something to another user’s crontab, use the -u option followed by
the user’s
- login as the root user
- Issue the command
crontab -l -u jimmo >/tmp/crontab.jimmo - Edit the file /tmp/crontab.jimmo using
vi . - Append the following line to the bottom of the file:
15 10,14 * * 1-5 /usr/local/bin/home_backup.sh - Save the file and exit
vi . - Active the new cron file with the command:
crontab -u jimmo /tmp/crontab.jimmo
Note: the script
As we saw, to add an entry, you simply add a new line. Save
the file, get out of your editor, and run the
I am not a big fan of this for safety reason. I know people who have done it and I have done it in the past myself and something wierd happened in the middle of making the changes (e.g. network connection dropped) and the old file was completed wiped out. So, I have grown used to redirecting the output to a file and then adding that. This way, should something go wrong, I always have the file.
Well, we added the entry, but it probably doesn’t say much. So, let’s take a look at the actual entry. Despite its appearance, each crontab entry consists of only six fields. The first five represent the time the job should be executed and the sixth is the actual command. The first five fields are separated by either a space or a tab and represent the following units, respectively:
- minutes (0-59)
- hour (0-23)
- day of the month (1-31)
- month of the year (1-12)
- day of the week (0-6, 0=Sunday)
To specify all possible values, use an asterisk (*). You can specify a single value simply by including that one value. For example, the second line in the previous example has a value of 10 in the first field, meaning 10 minutes after the hour. Because all of the other four time fields are asterisks, this means that the command is run every hour of every day at 10 minutes past the hour.
Ranges of values are composed of the first value, a dash, and the ending value. For example, the fourth line has a range (1-5) in the day of the week column, meaning that the command is only executed on days 1-5, Monday through Friday.
To specify different values that are not within a range, separate the individual values by a comma. In the fourth example, the hour field has the two values 10 and 14. This means that the command is run at 10 a.m. and 2 p.m.
Note that times are additive. Lets look at the example above:
The command is run 15 minutes after hour 10 and 14 on, Monday through Friday. Assume we wanted it to only run on on the 1st and 15, but only of they were a weekday. You might be tempted to do something like this:
As of this writing, cron cannot be configure to create complex conditions. If you need to schedule jobs of this nature, take a look at the Open Source Job Scheduler.
The crontab entry can be defined to run at different intervals than just every hour or every day. The granularity can be specified, for example, to every two minutes or every three hours without having to put each individual entry in the crontab.
Lets say we wanted to run the previous command not at 10 minutes after the hour, but every ten minutes. We could make an entry that looked like this:
This runs every 10 minutes: at the top of the hour (0 minutes after), 10 minutes after, 20 minutes after, and so on. Although this works, it could be done simpler by creating an entry like this:
This syntax may be new to some administrators, but is still pretty straightforward. The slash (/) says that within the specific interval (in this case, every minute), run the command every so many “units”. In this example, the units are minutes, so we are saying to run the job every 10 minutes. Specifying it as “*/5” would say to run it every 5 minutes.
- login as the root user
- Issue the command
crontab -l -u jimmo >/tmp/crontab.jimmo - Edit the file /tmp/crontab.jimmo using
vi . - Append the following line to the bottom of the file:
*/10 * * * * /usr/local/bin/command - Save the file and exit
vi . - Active the new cron file with the command:
crontab -u jimmo /tmp/crontab.jimmo
We can combine both intervals and range.For example, if the job was to run every 10 minutes, but only between 8 AM and 5 PM, Monday through Friday, that is normal work hours. As we mentioned above, a range is specified by the start and end values separated by a dash, so from 8 AM to 5 PM, it would look like this:
Note that in this case are using a 24 hour clock, so 5 PM is 17.
- login as the root user
- Issue the command
crontab -l -u jimmo >/tmp/crontab.jimmo - Edit the file /tmp/crontab.jimmo using
vi . - Append the following line to the bottom of the file:
*/10 8-17 * * * 1-5 /usr/local/bin/command - Save the file and exit
vi . - Active the new cron file with the command:
crontab -u jimmo /tmp/crontab.jimmo
In this example, the job runs every ten minutes (*/10), but only from 8-17 (8 AM to 5 PM) and only on weekdays (day 1 to day 5)
What if you wanted it to run at these times, but only every three minutes? The line might look like this:
One really nice thing that a lot of Linux dialects do is allow you to specify abbreviations for the days of the week and the months. Its a lot easier to remember that fri is for Friday instead of 5.
With the exception of
certain errors in the time fields, errors are not reported until cron runs the
command. All error messages and output is mailed to the users. At least
that’s what the crontab
Output is mailed to the user because there is no
real
Keep in mind that cron is not exact nor does it run in real-time. It synchronizes itself to the top of each minute. On a busy system in which you lose clock ticks, jobs may not be executed until a couple minutes after the scheduled time. In addition, there may be other processes with higher priorities that delay cron jobs. In some cases, (particularly on very busy systems) jobs might end up being skipped if they are run every minute.
Add a cron job to the system-wide cron table
Cron provides two ways of starting regular jobs. One is on a per-user basis, where the users themselves get to
manage their jobs. The second and newer method is the ability of the root user to add jobs to the global cron
table that run as a specific user. In this task, you will learn how to add jobs to the global cron table
The general syntax is the same as the standard crontabs,
with a couple of exceptions.
The first difference is the
The SHELL
The structure of the actual entries is pretty much the same with the exception
of the
We will assume that we want to start the script /usr/local/bin/backup.sh every day at exactly 4 AM as the user root.
- Login as as root
- Edit the file
/etc/crontab - Add the following line at the bottom of the file:
0 4 * * * root /usr/local/bin/backup.sh - Save the file and quit.
In this example, we specific the minutes (0) and the hour (4) and we used an asterisk (wildcard) for the remaining entries. This effectively means every day of every month. We could have also used an asterisk for any of the values, as needed. If we had wanted the script to only be started on Sundays, the entry might have looked like this:
Or, if we had wanted another script to be started once a year, it might look like this:
If both the day of the month and day of the week are specified, cron will run the job when either fields matches. For example, specifying “0 4 1 * 1” would mean the first of every month and every Monday.
Note that we logged in as root in order to edit the
Note that cron actually starts a shell before executing the respective command. As a result, basically anything applies
that would apply to any command issue from within a shell. For example, you can redirect
One thing I would like to
point out is that I do not advocate doing
Access is permitted to the cron facility
through two files, both in
- login as the root user
- Edit the file /etc/cron.allow
- Append the following line to the bottom of the file:
jimmo - Save the file and exit
vi .
If you have experience with other aspects of Linux, this mechanism may appear familiar, where the
file
Note that if neither of this files exist, then all users can access cron. Also, should
Some Linux distributions store the files in /var/spool/cron. So, to disallow access you would edit the file /var/spool/cron/deny.