Team LiB
Previous Section Next Section

Hack 70. Automate Your Life with cron

One of the great benefits of using computers is that they are ideal candidates for performing the uninteresting jobs humans get tired of doing. Most of us would be bored senseless making database backups everyday, cleaning out disks, updating report files, and managing system logs. These activities are typically linear, mundane processes that are straightforward enough to require little intervention, which makes them ideal candidates for automation.

One of the most fundamental pieces of the toolbox within all Unix-type operating systems is called cron. This small utility is like an alarm clock. When the alarm goes off, it tells the computer to do whatever you have configured it to do. As an example, if you perform a backup every day, you can get cron to perform this for you at a specific time. Another example is if you need to generate a weekly report about a projectcron can generate this report automatically.

An important point to note is that cron does not actually perform these activities itself. cron's only function is to trigger a specific process or series of commands at a certain time. When the specified time occurs, the commands and tools that are needed to complete the activity are run. As such, to automate a process on your computer, you need to determine how you can complete your task with a series of command-line tools. This usually means you need to create a script with the commands for cron to run at specified intervals.

9.2.1. Create a Cronjob

The cron program reads in a special file called a crontab. This file specifies jobs to be run and their times. You can access this file by running:

foo@bar:~$ crontab -e

This command uses the system's default command-line editor so that you can edit the crontab. If you want to set this editor to a different one (such as jed), set the $EDITOR environment variable prior to editing crontab:

foo@bar:~$ export EDITOR=jed

If this is your first use of cron, it is likely that your crontab is empty; unless some special system cronjobs were added (these automatically added crontabs are quite common in a number of Linux tools and utilities). Each cronjob consists of a single line containing the time of the cronjob, as well as the command to run.

A simple example of a crontab entry is:

30 3 1 * * /home/foo/createreport.sh

This example runs a script called createreport.sh at 3:30 a.m. on the first day of each month. The numbers on the left side of the line identify the time at which the script should be run, and the /home/foo/createreport.sh part shows the location and name of the script. It is always important that you use full and absolute paths when referring to scripts and files, as cron does not understand relative paths.

The numbers and stars on the left side of the line are entries in five different columns. Here are the columns, from left to right.


Minutes

This column indicates the minute part of the time in which the cronjob is to be run.


Hours

This column indicates the hour of the job and is given in 23-hour time (0_23). The time between midnight and 1:00 a.m. is the 0 hour.


Day

This is the number of the day in the month when the job is to be run.


Month

This is the month number between 1 and 12.


Day of the week

This is the day of the week, between 0 and 6, where 0 is Sunday.

In this example, you indicated the time as 3:30 a.m., and the day as the first day of the month. The two asterisks (*) show you want to run the script for each time increment in that columni.e., every day or month. As per the example, the * in the month and day-of-the-week columns means the cronjob will run every month and every day.

When you have finished editing the crontab, saved the file, and exited, the changes are automatically enabled. You can view the entries in the crontab file by running:

foo@bar:~$ crontab -l

You can also remove the entire crontab by using the -r option:

foo@bar:~$ crontab -r

9.2.2. More Advanced Crontabs

Although creating a crontab is fairly simple, if you need to have cronjobs running at specific intervals during a day, month, or year, this can result in a number of duplicated crontab entries with different times. To solve this problem, cron has a number of special symbols you can use to configure more elaborate times.

The first symbol is a comma (,), and you can use this to add multiple entries to a column. As an example, you can run the cronjob on the 5th, 10th, and 15th of each month with this line:

30 3 5,10,15 * * /home/foo/createreport.sh

Another useful symbol is the dash (-). You can use this to set a range for a particular column. For example, you can run the cronjob every day for the first week of a month with this line:

30 3 1-7 * * /home/foo/createreport.sh

A final symbol that is useful is the slash (/). You can use this to divide a column into regular intervals. In the following example, the */6 option means the cronjob will be run every six minutes:

*/6 * * * * /home/foo/createreport.sh

9.2.3. Make cron Email You

To cement your knowledge of cron let's try creating a cronjob that does something dynamic. The following cronjob emails you a daily report showing the current disk usage on your computer:

0 0 * * * echo -e "This is a summary of disk usage on your 
server:\n\n `df -h`" | mail -s 'Disk report for `hostname`
on `date`' foo@bar.org

In this example, use the echo command to create the text of the email; then embed the df (disk free) command in backticks and pipe the output to the mail command. Then the command creates the subject line of the email dynamically by calling the date and hostname commands.

This example illustrates that you can perform quite complex tasks as cronjobs, but that the crontab file itself can start to look very confusing. If you intend to do more complex tasks, such as the one in the previous example, it's probably better to put the code that does the actual work into a separate script file, and then just call it from the crontab. For safety it's also considered good practice to have your cron entry test that the script it is trying to call actually exists and can be executed. For the previous example, you can create a script called /home/foo/diskreport.sh like this:

#!/bin/sh
echo -e "This is a summary of disk usage on your 
server:\n\n `df -h`" | mail -s 'Disk report for `hostname`
on `date`' foo@bar.org

Then in your crontab, you can place an entry to call the script like this:

0 0 * * * test -x /home/foo/diskreport.sh || exit 0; /home/foo/diskreport.sh

The test -x checks whether the file exists and is executable, and it lets cron exit cleanly without an error instead of generating an error message if it can't run the script.

    Team LiB
    Previous Section Next Section