Skip to end of metadata
Go to start of metadata

Automating Your Systems With Cron

Category: Getting Started &nbsp

Cron is a tool designed to schedule tasks and automate performing them. It comes as standard with pretty much all Linux distributions, making it easy to schedule the running of scripts or applications. The tasks are ordered in a file called the crontab (cron table). Each user has their own crontab file as well as there being a global one usually stored in the /etc/crontab file.

These days, most Linux distributions come with default settings in the /etc/crontab file to make use of directories within /etc/ such as cron.hourly, cron.daily, cron.weekly and cron.monthly.  You can place scripts within those directories and they will be run as root at the appropriate time.  Scripts are usually run in alphabetical order, so bear that in mind if you have scripts that rely on the output of another completing beforehand. These directories will often have a lot of standard scripts for the operating system in them already, such as log rotation scripts, package manager update scripts etc, but they provide a very easy way to schedule tasks if those schedule timings fit with your requirements. If not, or you require your scripts to run as another user, you’ll need to look at editing the crontab file.

The crontab file is laid out in a simple format, and most modern distributions supply the default crontab files with comments explaining the format of the file. Comment lines all start with the hash character (#) and you can add your own comments throughout the file to annotate the lines you add.

The task lines follow a fairly simple format. The first section defines when cron should run the task, and the next section is the command it needs to run, be it a script or application.  Commands can be formatted much the same as at the command line, so should you want to, you can pipe multiple commands together as required.

For the timings you can use one of the predefined defaults, such as @yearly, @monthly, @weekly, @daily, @hourly and @reboot. They are all pretty self explanatory apart from @reboot, this one runs whenever the computer boots up. Other than that, tasks can be assigned using a five column number layout.

Column one is the number of minutes past the hour, from 0-59
Column two is the hour of the day, from 0-23
Column three is the day of the month, from 1-31, L meaning last day, and W meaning all weekdays
Column four is the month of the year, from 1-12
Column five is the day of the week, from 0 (Sunday) – 6 (Saturday), L combines to mean last of that day of the month.

Each column also takes a wildcard value of * which means every. You can also chain values together with a comma (,) for multiple times, a hyphen (-) for a range of times and a slash (/) to define increments of time. Below are a few examples and what they mean…

* * * * * Means every minute of every hour of every day.
30 1 * * 2         Means at 1:30am every Tuesday.
10 1,7,13,19 * * *         Means every day at 1:10am, 7:10am, 1:10pm, and 7:10pm.
0 9-17 W * *     Means all weekdays on the hour, every hour between 9am and 5pm.
0 23 L * *         Means at 11pm on the last day of the month.
45 13 * */2 6L  Means at 1:45pm on the last Saturday of every second month.
*/5 0-2,22-23 * * *        Means every 5 minutes between 10pm and 2am the next day.

A few other things to bear in mind are the cron permissions files. Stored in /etc, cron.allow and cron.deny change the way cron functions for users. If the file cron.allow exists then cron will only perform the tasks from crontabs belonging to users whose usernames are listed in the file.  Cron.deny works the other way round, all users will have the tasks in their crontabs unless they are listed in the cron.deny file.

Also the environment provided for the user when cron runs a job is not necessarily the same as for when you are logged in as the user. This may mean that jobs can fail to run for seemingly unexplainable reasons. The simple solution is to check your environment settings using the env command.

* * * * * env > ~/cron-environment

This will write the environment details to the cron-environment file in the user’s home directory every minute. Compare what is in the file with the output from the env command when you are logged-in to compare the differences. Debian, Ubuntu and many derivatives thereof enable you to place environment variables in the crontab file that will be obeyed for the following jobs within the file. So having the following lines in the crontab file…

PATH=/bin,/usr/bin,/sbin,/usr/sbin,/opt/randomapplication/bin
SHELL=/bin/bash
* * * * * env > ~/cron-environment

… should mean the cron-environment should contain the path and shell values from the crontab file. In CentOS and related distributions you generally have to use a shell script that sets the environment variables that the job requires and then runs the relevant command.

Cron by default will email the output of any job to the user that is running the job, assuming an email server is running on the server. If not, then an error will be noted in the logfiles. Generally I prefer to redirect the output to some logfiles so that I can have another script to analyse to make sure it ran correctly, saving me scanning through lots of emails.

Save this article