Cron Tutorial
The following are good links to cron tutorial pages:
#Using cron Basics
Unix Insider 8/25/00
At one time cron was easy to describe: It involved only one or two files. All you had to do was edit the files and -- voilą! -- cron did the rest. Now cron has become several files and several programs, and at first glance it seems quite complex. Fortunately, someone was clever enough to create a simplified interface along with the new complexity.
Cron is really two separate programs. The cron daemon, usually called cron or crond, is a continually running program that is typically part of the booting-up process.
To check that it's running on your system, use ps and grep to locate the process:
ps -ef|grep cron
root 387 1 0 Jun 29 ? 00:00:00 crond
root 32304 20607 0 00:18 pts/0 00:00:00 grep cron
In the example above, crond is running as process 387. Process 32304 is the grep cron command used to locate crond.
If cron does not appear to be running on your system, check with your system administrator, because a system without cron is unusual.
The crond process wakes up each minute to check a set of cron table files that 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. You don't need to concern yourself with the mechanics of the cron daemon other than to know that it exists and that it is constantly polling the cron table files.
The cron table files vary from system to system but usually consist of the following:
Any files in /var/spool/cron or /var/spool/cron/crontabs. Those are individual files created by any user using the cron facility. Each file is given the name of the user. You will almost always find a root file in /var spool/cron/root. If the user account named jinx is using cron, you will also find a jinx file as /var/spool/cron/jinx:
ls -l /var/spool/cron
-rw------- 1 root root 3768 Jul 14 23:54 root
-rw------- 1 root group 207 Jul 15 22:18 jinx
A cron file that may be named /etc/crontab. That is the traditional name of the original cron table file.
Any files in the /etc/cron.d directory.
Each cron table file has different functions in the system. As a user, you will be editing or making entries into the /var/spool/cron file for your account.
Another part of cron is the table editor, crontab, which edits the file in /var/spool/cron. The crontab program knows where the files that need to be edited are, which makes things much easier on you.
The crontab utility has three options: -l, -r, and -e. The -l option lists the contents of the current table file for your current userid, the -e option lets you edit the table file, and the -r option removes 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, unless it begins with a hash mark (#), which is treated as a comment. The six fields, which must be separated by white space (tabs or spaces), are:
Minute of the hour in which to run (0-59)
Hour of the day in which to run (0-23)
Day of the month (0-31)
Month of the year in which to run (1-12)
Day of the week in which to run (0-6) (0=Sunday)
The command to execute
As you can see, the "when to run" fields are the first five in the table. The final field holds the command to run.
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
Note that 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 sunday_job
9 45 3 1 * * monthly_report
10 * 15 * * * too_often
11 0 15 * * 1-5 better_job
$
Lines 2 through 4 contain comments and are ignored. 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 sunday_job is to be run at 1:25 a.m., only on Sundays.
Line 9 runs monthly_report at 3:45 a.m. of the first day of each month.
Line 10 is a typical cron table entry error. The user wants to run a task daily at 3 p.m., but has only entered the hour. The asterisk in the minute column causes the job to run once every minute for each minute from 3:00 p.m. through 3:59 p.m.
Line 11 corrects that error and adds weekdays 1 through 5, limiting the job to 3:00 p.m., Monday through Friday.
Now that you know cron basics, try the following experiment. Cron is usually used to run a script, but it can run any command. If you do not have cron privileges, you will have to follow as best you can, or work with someone who has them.
Use the crontab editor to edit a new crontab entry. In this example I am asking cron to execute something every minute:
$crontab -e
0-59 * * * * echo `date` "Hello" >>$HOME/junk.txt
$
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.
Close this cron table file. If you have cron privileges and have entered the command correctly, you will receive a receive that the file has been saved.
Use crontab -l to view the file:
$ crontab -l
# DO NOT EDIT THIS FILE
# installed Sat Jul 15
0-59 * * * * echo `date` "Hello" >>$HOME/junk.txt
$
Change to your home directory, use the touch command to create junk.txt in case it does not exist, and then use tail -f to open the file and display the contents line by line as they are inserted by cron:
$ cd
$ touch junk.txt
$ tail -f junk.txt
Sat Jul 15 15:23:07 PDT Hello
Sat Jul 15 15:24:07 PDT Hello
Sat Jul 15 15:25:07 PDT Hello
Sat Jul 15 15:26:07 PDT Hello
The screen will update once per minute as the information is inserted into junk.txt.
Stop the display by pressing Control-D.
Be sure to clean up the cron table files by using the crontab -e option to open the cron table file and remove the line you just created.
All commands executed by cron should run silently with no output. Because cron runs as a detached job, it has no terminal to write messages to. However, the best-laid plans of mice, men, and programmers are not without deviations from the expected course, and it is entirely possible that a command, script, or job may produce output or, heaven forbid, some actual error messages.
To handle that, cron traps all the output to standard out or to standard error that has not been redirected to a file, as in the example just tested. The trapped output is dropped into a mail file and is sent either to the user who originated the command or to root. Either way, it conveniently traps errors without forcing cron to blow up or abort.
--------------------------------------------------------------------------------
#Scheduled Activity: cron and at
by John Raithel
The Linux utilities cron and at are related commands. The cron utility allows you to schedule a repetitive task to take place at any regular interval desired, and the at command lets you specify a one-time action to take place at some desired time. You might use crontab, for example, to perform a backup each morning at 2 a.m., and use at to remind yourself of an appointment later in the day.
Using crontab
The word ``crontab'' is a UNIXism for chron table, or time table. You create a table in the required format, specifying commands and times to execute the commands. Commands you put in the table can be any executable programs, for example, a command in /usr/bin or a shell script you wrote. You use the crontab command to create, edit, or list the table, and the system cron daemon reads the table and executes the commands at the times specified.
The cron Daemon
The cron daemon is normally executed at system startup and does not exit. On my Linux system, the cron daemon is actually Matthew Dillon's crond, and is started in /etc/rc.d/rc.M with the following line:
/usr/sbin/crond -l10 >>/var/adm/cron 2>&1
On some Linux systems, Paul Vixie's cron daemon is used, in which case the name of the daemon is simply cron. Also, on systems with newer versions of init, cron is started from the /etc/init.d/cron script.
You can check to see if a cron daemon is running on your system with a command such as the following:
$ ps -ax | grep cron
raithel 733 pp0 S 0:00 grep cron
root 25 ? S 0:00 /usr/sbin/crond -l10
In this case, we see that the crond daemon is indeed running.
The crontab Table
When the cron daemon starts, it reads the various crontab tables in the crontab directory, normally /usr/spool/cron/crontabs. To create or change your crontab file, use crontab's -e option:
$ crontab -e
You are placed in a text editor with a copy of your current crontab file if it exists, or a blank file if it does not. The text editor you get is determined by the setting of your VISUAL (or EDITOR, if VISUAL is not set) environment variable, and is usually the vi editor if you have not specified otherwise.
To schedule commands with crontab, you must use the format crontab recognizes in a file. The format is not exactly mnemonic, so I create a crontab file with a commented-out header that provides the necessary information:
# minute (0-59),
# hour (0-23),
# day of the month (1-31),
# month of the year (1-12),
# day of the week (0-6, 0=Sunday),
# command
Each crontab entry is a single line composed of these six fields separated by whitespace. Specify the minute a command is to be executed with the digits 0 through 59 in the first field, the hour with 0 through 23 in the second field, the day of the month with 1 through 31 in the third field, the month of the year with 1 through 12 in the fourth field, and the day of the week with 0 through 6 in the fifth field. Place the command to be executed in the sixth field.
At first glance it may appear that redundant or conflicting information is required because there are two ``day'' fields---day of the month and day of the week, but really this is just to permit different scheduling algorithms. For instance, you may want to be reminded to attend a meeting every Tuesday, or to pick up your paycheck every 15th of the month. Enter an asterisk (*) in the day field you are not using. You can use both day fields if you prefer to have the command execute on, say, the fifteenth of the month as well as every Tuesday.
Ranges are specified with a dash. If you want to specify the eighth through the fifteenth days of the month, enter 8-15 in the third field. Non-consecutive entries in a field are separated by commas, so 1,15 in the third field means the first and fifteenth of the month. To specify all values for a field, for example every month of the year, enter an asterisk (*) in the field. (Note that to specify every day you must enter * in both day fields.)
Here is an example crontab file with two entries:
# minute (0-59),
# hour (0-23),
# day of the month (1-31),
# month of the year (1-12),
# day of the week (0-6, 0=Sunday)
# command
12 4 * * * /usr/local/bin/backup
5 3 10-15 4 * echo "taxes due" | mail jones
The first line after the comments causes a backup script to execute early each morning at 4:12 a.m., and the second line causes the user jones to get a mail message for six days in April as a reminder that taxes are due. In general, it's a good idea to execute crontab commands at off hours like this to reduce any affect on system load during normal usage hours.
If you don't specifically redirect standard error or standard output, they are mailed to you as owner of the crontab file when the command executes. In the example above, if the user jones cannot be found, you would be mailed the output as well as an error message.
After editing the crontab file, save it and exit from the editor. A file is created for you in the crontab directory. For example, the crontab for root is the file /usr/spool/cron/crontabs/root. This file is read by the system cron daemon and stored in an internal format where it will remain to be periodically executed until it is changed or deleted.
To view your current crontab file, use the -l (for ``list'') option:
$ crontab -l
To delete your file, use:
$ crontab -d
If you are superuser, you can delete any user's crontab file with:
# crontab -d username
where username is the user's login name.
The crontab commands discussed above work fine on my Linux system, and should work on System V and BSD UNIX systems as well. One thing to be aware of when using crontab on other systems or moving crontab files to other systems, is that some cron daemons allow the superuser to restrict crontab service by the creation of cron.allow and cron.deny files. Refer to the specific system documentation for details.
Also, most versions of cron provide an /etc/crontab file which has an extra field in it---the user as which to execute the command. Again, check the documentation for your version of cron for more details.
Using at
Use at when you want to execute a command or multiple commands once at some future time.
In Linux, the at command requires that the atrun command be started in root's crontab file. Many Linux distributions ship with at enabled, but some do not. To enable the at utility on your system, become superuser and edit root's crontab file:
$ su root
Password:
# crontab -e
and add the following line:
* * * * * directory/atrun
where directory is the location where the atrun executable is stored. On my system that's /usr/lib, so the entry is:
* * * * * /usr/lib/atrun
This causes atrun to be executed every minute. After a minute or so of adding the atrun line and saving the crontab file, any existing at commands are evaluated and executed if the time is right. (Before this, you may have been able to enter at commands, but they were never executed.)
To demonstrate the at command, let's have it print ``hello'' on your current terminal window after a few minutes. First, get the time and your current terminal device:
$ date
Tue Oct 3 15:33:37 PDT 1995
$ tty
/dev/ttyp2
Now run the at command. Specify a time in the command line, press Return, and then enter the command, followed by another Return and a Control-D:
$ at 15:35
echo "hello" > /dev/ttyp2
^D
Job c00ceb20b.00 will be executed using /bin/sh
The at command takes input up to the end-of-file character (press Control-D while at the beginning of a line). It reports the job number and informs you that it will use /bin/sh to execute the command. In two minutes, hello should appear on the display of /dev/ttyp2. Note that you can enter a series of commands, one per line---at will read each line up to the end-of-file and execute the file as a /bin/sh shell script at the specified time. Suppose you want to set an alarm. One way to tell at to do something is to use the relative form of timing, specifying a time relative to now. If you want your computer to beep at you in 25 minutes, enter:
$ at now + 25 minutes
echo ^G > /dev/ttyp4
^D
Job c00ceb7fb.00 will be executed using /bin/sh
and you are beeped in 25 minutes. There is a great deal of flexibility allowed in entering time specifications. For example, at recognizes military time, ``am'' and ``pm'', month abbreviations, times including the year, and so on. My at man page even claims that at accepts teatime, noon, and other constructs. Refer to the at man page for more examples of valid time specifications.
You must tell at your tty location or it won't send output to your terminal window. If you prefer, you can receive mail:
$ at 4:55pm Friday
echo '5 p.m. meeting with Carol' | mail raithel
^D
Job c00ceb7fb.01 will be executed using /bin/sh
To get a list of your pending at jobs, enter:
$ atq
If you are superuser, atq shows you the pending at jobs of all users. To delete a job, enter:
$ atrm job_number
where job_number is the job number returned by atq. The superuser can also remove other user's jobs.
A Reminder Script Using at
The following is a simple script that makes it easier for me to use at to send myself reminders. The script sends mail to the user containing the message line(s) entered at the prompt at the time specified. It also displays some syntax examples of how to specify time, which I find a useful memory refresher.
Note that the script as written requires you to have a Temp directory in your home directory. I created a $HOME/Msgs rather than use something like /usr/tmp so that the messages are more private until they are deleted by the script.
#!/bin/sh
echo "Enter your reminder message.
When finished, enter a period (.) at
the beginning of a line and press Enter.
(Or press Ctrl-C or DEL to exit.)"
while :
do
read MESSAGE
if [ "$MESSAGE" = "." ]
then
break
else
echo $MESSAGE >> $HOME/Msgs/message.$$
fi
done
cat << !!
Enter time and day you want to receive
the message, for example:
0815am Jan 24
8:15am Jan 24
now + 1 day
5 pm Friday
Then press Enter.
!!
read TIME
echo "at $TIME mail $LOGNAME $HOME/Msgs/message.$$"
at $TIME << !!
mail $LOGNAME < $HOME/Msgs/message.$$
rm -f $HOME/Msgs/message.$$
!!
exit 0
Some Final Thoughts
The user's interface to the crontab and at commands is very similar across different versions on UNIX, but implementations of underlying directory structures, daemons, and access controls may differ. Be sure to review your system documentation to take advantage of all aspects of these powerful commands.
There's practically no limit to the use of crontab and at, but a few words of warning. First, consider security issues when enabling user crontab and at permissions. Obviously, a disgruntled co-worker could leave a ``time-bomb'' of some sort, limited only by their other permission restrictions. Many versions of crontab and at allow you to specify ``allow'' and ``deny'' files to control which users have access to the utilities. You could also use root's crontab to check for and remove user crontabs (or any other files) if you want to.
Also, debug your crontab file entries thoroughly. Check that they are working. These entries are usually scheduled to execute at times of low-usage so it is unlikely you'll be around to observe them at the time.
--------------------------------------------------------------------------------