Cover V02, I04


Using cron and crontab

Larry Reznick

cron(1) automatically starts when multiuser mode (init level 2) begins and stops when the system is shut down (init level 0). Two rc files control the starting and stopping of cron. The names of those rc files are usually /etc/rc2.d/S75cron, which starts cron, and /etc/rc0.d/K75cron, which kills it. These files are typically hard links to /etc/init.d/cron.

When cron is started, it reads the contents of every file in /usr/spool/cron/crontabs, which may be a symbolic link to /var/spool/cron/crontabs. The crontabs directory contains the textfile cron tables for each user. The crontabs, named after each user who has one, identify what each user wants the system to do at any given time. Older versions of UNIX allowed only root to have a crontab. System V provides two files that let the system administrator configure who may use cron and who may not: /usr/lib/cron/cron.allow and /usr/lib/cron/cron.deny. cron.allow is a textfile inclusion list, containing the names of users specifically allowed to use cron. Users who aren't in that list can't use cron. cron.deny is a textfile exclusion list containing the names of users specifically denied the use of cron. Anyone not named in that list can use cron. To allow all users access to cron, eliminate the cron.allow file and create a zero-length cron.deny file. Otherwise, use only one of these mutually exclusive files to limit user access to cron.

cron also controls the use of at(1) and batch(1). You would use the crontabs for regularly scheduled tasks; for a one-time-only task, use at or batch instead. The difference between at and batch is that at does the task at a specific time while batch starts doing it right away (though only when the system load is low). The batch job will take longer because it is being nice(1) to the system. Since at and batch are for one-shot tasks, they aren't used as often as cron.

cron wakes up once every minute to see if something needs to be done. If so, it starts the task, acting in almost every way as if it is the user when running the task. Unfortunately, cron cannot reference the user's normal environment, which is set up by execution of a .profile, or .cshrc and .login This can cause trouble when cron is executing shell scripts, since cron doesn't know the user's path. Thus, what executes for you on your command line may not execute for cron. cron only has /bin, /usr/bin, and /usr/lbin in its path. Furthermore, cron always executes the crontab commands using Bourne Shell (/bin/sh). If you need a different shell, you must make cron start the shell as part of its command line, or the shell must be identified within the shell script. To avoid these path problems, programs named within the shell script or used directly within the crontab command line must either have full pathnames or the PATH variable must be set in the script or crontab command line.

When cron executes a task, any output to standard output or standard error is collected and mailed to the user whose crontab is executing. This can be handy sometimes, but most of the time the mail represents noise. To eliminate the mail, put the following at the end of the crontab command line:

>/dev/null 2>&1

This causes the standard output to be redirected to /dev/null (the bit bucket), and standard error to be redirected to wherever standard output is going.

To create a crontab file, use the crontab(1) command. Any user not denied access to cron may execute

crontab -l

to list his/her current crontab file. Root can follow that with a user's name to list another user's file. Another command,

crontab -e

is used to edit the current crontab file using your VISUAL editor, but some UNIX versions don't support that and others I've used are buggy. I get around the problem by using

crontab -l >crontab.user

which takes the listing output and writes it in a file named crontab.user where user is the actual username. Then, I manually start up the editor.

Other than comments, which begin with a # symbol, all lines follow the same six-field format. They are:

1.	minute (0-59)
2.	hour (0-23)
3.	day (1-31)
4.	month (1-12)
5.	weekday (0-6, 0 is Sunday)
6.	command line

Each field is separated by a space or a tab. The first five fields represent the time and date combination for when the command, written in the sixth field, is to be executed. If an asterisk (*) is used in a field instead of a number, all possible values will apply. For instance, in the following lines,

1 5 * * * command1
* 23 * * * command2

command1 will be run at 5:01 A.M., every day of every month without regard to the weekday, while command2 will run every minute from 11:00 P.M. to 11:59 P.M. It is not usually a good idea to put an asterisk in the minute field. Multiple values for a single field can be used if separated by commas. For example, the following lines,

5,35 * * * * command3
1,21,41 * * * * command4
7,22,37,52 * * * * command5

execute command3 twice every hour, execute command4 three times every hour, and execute command5 four times every hour. Specify ranges of time by separating the beginning and ending of a range with a hyphen. To execute a program on certain days, you must use the following lines:

3 2 * * 2 command6
47 4 * * 1-5 command7
17 18 1 1 * command8
17 18 1 2-12 * command9
1 0 1 * 0 command10

command6 executes at 2:03 A.M. every Tuesday. command7 executes at 4:47 A.M. every Monday through Friday, but never Saturday or Sunday. command8 and command9 are each executed at 6:17 P.M. on the first of every month, but command8 executes on January 1, while command9 executes every remaining month. Finally, command10 executes at one minute after midnight on either the first of every month or on Sunday.

Once the crontab entries are set up the way you want, you install the crontab file by using the command:

crontab crontab.user

where the first word is the crontab(1) command and the second word is the name of the file you have been editing. It is useless to directly edit the crontab files in /usr/spool/cron/crontab, since cron only reads those files when it starts, usually at bootstrap time. The crontab command will install a copy of your file in the /usr/spool/cron/crontab directory, named with your username, and force cron to read it right away. You may then delete your copy of the file or keep it as you please.

The system is typically installed with crontab files for root and some other pseudo-users, such as adm and sys. It is worthwhile for the system administrator to learn what is in there to see what the system does behind everybody's back. The root crontab usually includes the uucp support handling (what time does your system do its uucp polling?), cleanup (which directories are cleaned up, how frequently, and should any be added to the list?), and some parts of system accounting. The adm crontab usually handles most of system accounting, while the sys crontab usually does the performance collection. Most of the serious system administration cron jobs are put into the root crontab because cron runs those jobs with root's permissions. Often, an su(1) command is run to make root act like another user for a particular task, and root can bypass the other user's password.

About the Author

Larry Reznick has been programming professionally since 1978. He is currently working on systems programming in UNIX and DOS. He teaches C language courses at American River College in Sacramento. He can be reached via email at: rezbook!