Automating tasks is one of the best ways to keep a system running smoothly. If you take all the repetitive system administration commands you need to run regularly and have them run in background without your direct involvement, system administration becomes much less onerous and bothersome. The utilities cron and at were developed to help make your job easier. Both allow you to execute commands automatically at specified times, without bothering you.
The cron (short for chronograph) utility is designed to allow commands to execute at specific times without anyone directly initiating them. Linux loads cron as a clock daemon when the system starts up. (The cron utility is usually run from an rc file entry; you can disable it by commenting out the line that starts cron.) When operating, cron reads the days and times it is supposed to execute a task from a file called the crontab file.
Whenever one of the crontab file's day and time specification entries matches the system's date and time, the cron daemon executes the command. The cron utility doesn't just execute the task once; the task is run again whenever the specified day and time match the system day and time. The task continues to be run until you terminate the cron utility or modify the crontab file. The automatic execution of tasks means that cron is ideal for automating regular system administration tasks such as tape backups, database reorganization, and general file cleanups (such as emptying log files and queues).
On most systems, access to cron is limited to the system administrator, although you can easily activate it for some or all users on your system. System administrators control who can send processes to be executed by cron through one of two different files, often called /usr/lib/cron/cron.allow or /usr/lib/cron/cron.deny. Many Linux systems use the names /etc/cron.d/cron.allow and /etc/cron.d/cron.deny. Both files have one username (which matches the entry in /etc/passwd) per line.
The file /usr/lib/cron/cron.allow (or /etc/cron.d/cron.allow) can contain a list of all usernames that are allowed to use cron. For example, the file
tparker yvonne bill
allows only the logins tparker, yvonne, and bill (as well as the superuser) to submit anything to cron.
The file /usr/lib/cron/cron.deny can contain a list of usernames that are not allowed to use cron. For example, the file
allows everyone except the logins walter and anne to use cron.
By using one of these optional files, system administrators can control cron usage. If neither the cron.allow or cron.deny files exist, only the superuser (root) can submit processes to cron. To allow all users to use cron, create an empty cron.deny file.
To instruct cron to process commands at particular days and times, you use a utility called crontab. The crontab program reads a file that contains the details of what you want cron to do and queues it. In addition, crontab performs several other administrative tasks, such as displaying your current cron task list, removing the list, and adding new tasks to the list.
The file that crontab reads to determine what you want to submit to cron is usually named crontab for convenience, although you can call it anything. The crontab utility has a command option that allows you to specify the filenameyou want it to use. If you don't use this option, the crontab utility reads the default filename, crontab.
The crontab instruction file has a simple structure. The file consists of one complete line for each process to be submitted that specifies when to run the process and what command to execute. The format of each line is as follows:
minute hour day-of-month month-of-year day-of-week command
An example two-line extract from a crontab file looks like the following:
20 1 * * * /usr/bin/calendar - 0 2 * * * /bin/organize_data
Each line in the crontab file has six columns separated by whitespace (spaces or tabs). The columns, from left to right are as follows:
This rather strange (at first glance) format is necessary to enable you to completely specify when a process is to run. Without the five different categories for days and time, you couldn't uniquely specify any event that occurs one or more times a month. These columns are quite easy to complete.
The last column contains the command or script filename that is to be executed. A script that is to be executed can have many lines and call other scripts, or it can be only a single line. The first process is initiated when the crontab file matches the day and time. It is important to provide an absolute pathname to the command (even if it's in your PATH), as the cron jobs do not inherit your environment variables and thus don't know where to look for commands. Also, you must have execute permission for the utility or script. If you are submitting crontab files as a user (not superuser), you must have file permissions or ownership set to allow you normal access, as cron executes the processes as though you owned them.
Each time and day column in the crontab file can contain a single number anywhere in the range of valid numbers, two numbers separated by a minus sign to show an inclusive range (such as 1-5 to show one through five), a list of numbers separated by commas to mean all of the values explicitly specified, or an asterisk meaning all legal values.
Look at the following sample lines of a crontab file to see how this file works:
20 1 * * * /usr/bin/calendar - 0 2 1 * 0 /bin/organize_data 10,30,50 9-18 * * * /bin/setperms
This example specifies three different processes. The first command is /usr/bin/calendar - (the hyphen is an important part of the command). This process is executed at 20 minutes past one in the morning (cron uses a 24-hour clock) every day of the week and each day of the year. The asterisks mean all values(every day).
At 2:00AM, a script file called /bin/organize_data is executed on the first day of every month (the 1 in the third column) and every Sunday (the 0 in the fifth column). If the first day is a Sunday, it executes only once, of course. The third line shows that a script called /bin/setperms runs at 10, 30, and 50 minutes past the hour every hour between 9:00AM and 6:00PM (18:00), every day of the week.
The entries in a crontab file do not have to be in any special order. As long as each entry is on a line by itself and has all six fields specified properly, cron organizes the information for its own use. If you have an error in the crontab file, cron mails you a notice of the problem when it processes your file. (This notice can be annoying if you have the entry with the error set to execute often because cron mails you each time it tries to execute the entry and finds a problem. Your mailbox quickly gets filled with cron error messages.)
Keep the crontab files in your home directory and name them crontab, unless you want to have several versions of the files, in which case you can use any naming convention you want. Keeping the names simple helps you identify which file you want cron to execute.
After you write your crontab file, you can submit it for cron to execute. When you submit a crontab file, a copy of the file is made and kept in a cron directory, usually /usr/spool/cron/crontabs. The file has the name of the submitting user. A crontab file submitted by yvonne, for example, has the name /usr/spool/cron/crontabs/yvonne. Any crontab files submitted by the superuser usually have the name root.
To submit your crontab file to cron, use the crontab command followed by the name of the file with the cron commands in it. For example, the command
submits the file called crontab in the current directory to cron. If you had previously submitted a cron file, it is removed and the new file is used instead.
Always submit a change to cron using the crontab file and an edited ASCII file. Never make changes to the file in /usr/spool/cron/crontabs; the changes will not be read by cron and can potentially mess up any existing cron tasks.
You can see what you have submitted to cron by using the -l (list) option. This option shows all the crontab entries the cron utility knows about (essentially displaying the contents of the file with your username from /usr/spool/cron/crontabs). For example, the command
shows all cron tasks for the user who submits the command.
To remove your crontab file and not replace it, it use the -r (remove) option. This option erases the file with your filename from the /usr/spool/cron/crontabs directory. The syntax for this command is as follows:
Finally, you can call up your current cron file and start an editor (the default editor as defined by your environment variables or a system default variable) by using the -e (editor) option. When you issue the command
crontab reads your existing crontab file and loads it into the default editor (such as vi). When you save the edited file, it is submitted to cron automatically.
Changes to the crontab file are usually effective within five minutes at most, as cron reads the contents of the /usr/spool/cron/crontab file at least once every five minutes and often more frequently (most Linux systems have cron check the directories every minute). Because you have to wait for cron to check the contents of the crontab file, execution of a process you have submitted to cron can sometimes be delayed by a few minutes, so don't rely on cron to be exactly on time. The more heavily loaded a system is, the greater the delay in execution.
On some systems, system administrators can log all cron usage by modifying an entry in the file /etc/default/cron. One line in the file should contain the variable CRONLOG. If you set the value equal to YES, cron logs every action it takes to the file /usr/lib/cron/log. Not all versions of Linux allow cron logging. If you do enable cron logging, check the log file frequently as it can grow to a large size quite quickly.
The crontab file can contain any type of command or shell script, as long as the line is valid (in other words, it could be executed from the shell prompt). A common problem with many shell commands is the generation of output, especially error messages, which is mailed to you and can clog up your mailbox quickly. For this reason, if you anticipate error message output (from a compiler, for example), you can redirect the output to /dev/null. For example, the command
0 * * * * date > /tmp/test1 2>/dev/null
sends the output of the date command to a file called /tmp/test1 every hour and sends any error messages to /dev/null (which essentially discards such messages). You can do the same with the standard output, if you want, or you can redirect it elsewhere. For example, the cron command
30 1 * * * cat /usr/tparker/chapt* > /usr/tparker/archive/backup
concatenates all the files starting with chapt in /usr/tparker into one large file called /usr/tparker/archive/backup. Again, you can redirect the the standard output.
You can also do piping in the crontab file. For example, if you have a list of users who are logged in the system during the day in the file /tmp/userlist, you can have a crontab entry that looks like the following:
0 1 * * * sort -u /tmp/userlist | mail -s"users for today" root
This line sorts the output of /tmp/userlist so that there is only one entry for each user (the -u or unique option) and mails it to root.
An important point to remember with cron is that all commands are executed, by default, in the Bourne shell (or bash, if it is the sh equivalent on your system). If you use C shell commands, the cron task will fail.
The at program is very similar to cron, except that at executes a command only once at a prespecified time and cron keeps executing a command. The format of the at command is as follows:
at time date < file
You can specify most of the at command parameters in several different ways, which makes the at command versatile. you can specify the time, for example, as an absolute time (18:40 or 22:00) or as two digits that are taken as hours (so 10 means ten o'clock in the morning as a 24-hour clock is the default). You can add an am or pm to the time to make it clear which you mean, so 10pm is unambiguously in the evening.
The at command handles a few special words instead of time designations. The command recognizes the words noon, midnight, now, next, and zulu for GMT conversion. (Some at versions generate an error message if you try to execute a command with the time set to now.)
The date is an optional field that you use when the time is not specific enough. If you don't supply a date, at executes the command the next time the specified time occurs. If you specify a date, at waits until that date to execute the command. You can give the date as a month's name followed by a day number (May 10) or a day of the week (either spelled out in full or abbreviated to three characters). You also can specify a year, but this specification is seldom necessary. As with the time, the at command recognizes two special words that relate to dates: today and tomorrow (although the word today is redundant as the command executes today by default if the time is set properly).
The file to be read in as input to the at command can be any file with commands in it. Alternatively, you can type in the commands and press Ctrl+d when you're finished, although this method is not recommended due to the high potential for error.
Suppose you have a file called reorg.data with the following commands in it:
/usr/tparker/setperms /usr/tparker/sort_database /usr/tparker/index_database /usr/tparker/clean_up
If you want to execute this file at 8:30PM, issue any one of the following commands:
at 20:30 < reorg.data at 8:30 pm < reorg/data at 20:30 today < reorg.data
Even more variations are possible, but you can see the syntax. If you want to execute the command on Friday, issue the command in one of these formats:
at 8:30 pm Friday < reorg.data at 20:30 Fri < reorg.data
Some versions of at are even more talented and handle special words. For example, this command
at 0900 Monday next week < reorg.data
executes the commands next week on a Monday. Not all versions of at can handle these complex formats, however. Check the man pages to see which formats your version supports, or just try these formats and see whether you get an error message.
When you submit a program to at for execution, you get back a job identification number. This number uniquely identifies the at command you just issued. For example, look at the output from this at command:
$ at 6 < do_it job 827362.a at Wed Aug 31 06:00:00 EDT 1995
In this case, the job ID is 827362.a and the ID is needed to make any changes to the job.
You can list all the jobs you have queued with at using the -l (list) option. The output usually tells you when the command is set to execute, but not what the command is:
$ at -l user = tparker job 827362.a at Wed Aug 31 06:00:00 EDT 1995 user = tparker job 829283.a at Wed Aug 31 09:30:00 EDT 1995
Some versions of Linux may support the shorter form of the command with atq (display the at queue). If you get an error message when you issue the atq command, you have to use the at -l format.
To remove an at job from the system, you need the job ID and the at -r (remove) command. For example, the command
at -r 2892732.a
removes the specified job. Linux doesn't return any message to indicate the job has been canceled, but you will see the job is gone if you list the queue. You can remove only your own jobs (root can remove any). Some Linux versions support the atrm command as well as the -r option.
All jobs that are queued to at are kept in the directory /usr/spool/cron/atjobs with the job ID number as the filename. As with cron, an at.allow and an at.deny file in either the /usr/lib/cron or /etc/cron.d directory controls who can and can't use at. As with cron, create an empty at.deny file if you want all users on your system to be able to use at.
When an at job executes, all output (standard output and error messages) is mailed back to the username who submitted the job unless it has been redirected. The at command retains all the environment variables and directory settings of the user. If you look at a queued job in /usr/spool/cron/atjobs, you see all the variables defined prior to the command to be executed.
As you have seen, cron and at are quite easy to use. They are also a system administrator's best friends, as you can automate tiresome tasks like cleaning up databases, checking disk space, flushing log files, and making tape backups with cron or at. Although cron and at can't do everything for you, they can handle repetitive tasks with ease.
Most Linux systems have a number of sample cron files supplied with the operating system. Examine those files (or list the current crontab file while logged in as root) to see what the operating system wants to execute on a regular basis. Use those commands as the starting point and add your own commands. Probably the worst that can happen if you mess up a crontab file is that you will get a lot of mail!