Scheduling Tasks with CRON
Cron makes things happen automatically (FreeBSD 5.2)
Posted 09.07.2005 | Updated 02.06.2008 | Contributed by Andy Mallett


Cron lets you schedule programs and scripts to run and predetermined times. The cron daemon, usually called cron or crond, is a runs all the time from bootup.

The crond process wakes up each minute to check its cron table files, which list tasks and the times when those tasks are to be performed. If any programs need to be run, it runs them and then goes back to sleep.

Cron just beavers away in the background, constantly sniffing the cron table files for configuration information.

The cron table files vary from system to system but in FreeBSD it's usually /etc/crontab.
The crontab command has three options:
  • crontab -l list the contents of the current table file for your current userid
  • crontab -e edit the table file
  • crontab -r remove a table file
A cron table file is made up of one line per entry. An entry consists of two categories of data: when to run a command and which command to run.

A line contains six fields, each of which must be separated by a space (or tab):
  1. Minute of the hour in which to run (0-59)
  2. Hour of the day in which to run (0-23)
  3. Day of the month (0-31)
  4. Month of the year in which to run (1-12)
  5. Day of the week in which to run (0-6) (0=Sunday)
  6. The command to execute
An entry in the first five columns can consist of:
  • A number in the specified range
  • A range of numbers in the specified range; for example, 2-10
  • A comma-separated list consisting of individual numbers or ranges of numbers, as in 1,2,3-7,8
  • An asterisk that stands for all valid values
Lists and ranges of numbers must not contain spaces or tabs, which are reserved for separating fields.

A sample cron table file might be displayed with the crontab -l command. The following example includes line numbers to clarify the explanation.
1     $ crontab -l
2     # DO NOT EDIT THIS FILE
3     # installed Sat Jul 15
4     #min    hr   day   mon   weekday  command
6     30      *     *     *     *       some_command
7     15,45   1-3   *     *     *       another_command
8     25      1     *     *     0       do_this
9     45      3     1     *     *       and_this_too
10    *       15    *     *     *       call_home
11    0       15    *     *     1-5     run_away
$
Lines 2 - 4 are just comments fields. Line 6 runs the command some_command at 30 minutes past the hour. Note that the fields for hour, day, month, and weekday were all left with the asterisk; therefore some_command runs at 30 minutes past the hour, every hour of every day.

Line 7 runs the command another_command at 15 and 45 minutes past the hour for hours 1 through 3, namely, 1:15, 1:45, 2:15, 2:45, 3:15, and 3:45 a.m.

Line 8 specifies that do_this is to be run at 1:25 a.m., only on Sundays.

Line 9 runs and_this_too at 3:45 a.m. of the first day of each month.

Line 10 is actually a fine example of a common screw up. The user wants to run a task daily at 3 p.m., but has only entered the hour. The asterisk in the minute column will actually cause the job to run once every minute for each minute from 3:00 p.m. to 3:59 p.m.

Line 11 corrects that error and adds weekdays 1 to 5, limiting the job to 3:00 p.m., Monday to Friday.

The sixth field contains the command to echo the output from date (note the reverse quotes around date), followed by "Hello", and also the command to append the result to a file in my home directory, which is named junk.txt.

One thing to note about the executable: cron wants to run scripts from the user's home directory. So if the job is running as user fred, then the script must be run from /home/fred. If it's run as root user, then the executable must be sitting in root's own home dir, /root.

All commands executed by cron should run quiet as a mouse, with no output. To check that cron is running..
ps -aux | grep cron
root     440  0.0  0.4  1336 1040  ??  Is    3:29PM   0:00.06 /usr/sbin/cron
root    1103  0.0  0.3  1448  880  p0  S+    5:42PM   0:00.00 grep cron
Because cron runs as a 'detached job', it has no terminal to write messages to. However, a command or script could produce output or error messages.

If this happens, cron will put all the output to standard out or to standard error if it has not been redirected to a file. The output is lobbped into a mail file and is sent either to the user who originated the command or to root, without stopping cron while it does so.

Here's one of my own examples of using cron to sechedule a job.

Cron and Emails

If you're somebody who likes getting emails then you'll LOVE cron. He sends an email to the cron job owner (usually root), every time he performs a scheduled task. Which is really whoop-dee-do if you have jobs running every 5 minutes like I have.

To prevent this shitload of emails traversing your server farm, add the following to the end of the lines of the jobs which you don't want to be emailed about, in crontab, :

>/dev/null 2>&1

For example..

00,05,10,15,20,25,30,35,40,45,50,55  * * * *  /bin/scriptname  >/dev/null 2>&1


The above looks a bit unwieldly, so the following will also achieve the same result of running the script every 5 minutes..

*/5 * * * *  /bin/scriptname  >/dev/null 2>&1


Further reading

http://www.adminschoice.com/docs/crontab.htm
http://www.rt.com/man/crontab.5.html
http://weather.ou.edu/~billston/crontab