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.
 |