Scheduling System Tasks

Scheduling System Tasks

Frequently, you need to run a process unattended or at off-hours. The at facility is designed to run such jobs at specific times. Jobs you submit are spooled in the directory /var/spool/at, awaiting execution by the at daemon atd. The jobs are executed using the current directory and environment that was active when the job was submitted. Any output or error messages that haven't been redirected elsewhere are e-mailed to the user that submitted the job.

The following sections describe how to use the at, batch, and cron facilities to schedule tasks to run at specific times. These descriptions also include ways of viewing which tasks are scheduled and deleting scheduled tasks that you don't want to run anymore.

Using at.allow and at.deny

There are two access control files designed to limit which users can use the at facility. The file /etc/at.allow contains a list of users that are granted access, and the file /etc/at.deny contains a similar list of those who may not submit at jobs. If neither file exists, only the superuser is granted access to at. If a blank /etc/at.deny file exists (as in the default configuration), all users are allowed to utilize the at facility to run their own at jobs.

Specifying when jobs are run

There are many different ways to specify the time at which an at job should run (most of which look like spoken commands). Table 12-6 has a few examples. These are not complete commands — they only provide an example of how to specify the time that a job should run.

Table 12-6: Samples for Specifying Times in an at Job

Command Line

When the Command Is Run

at now

The job is run immediately.

at now + 2 minutes

The job will start 2 minutes from the current time.

at now + 1 hour

The job will start one hour from the current time.

at now + 5 days

The job will start five days from the current time.

at now + 4 weeks

The job will start four weeks from the current time.

at now next minute

The job will start in exactly 60 seconds.

at now next hour

The job will start in exactly 60 minutes.

at now next day

The job will start at the same time tomorrow.

at now next month

The job will start on the same day and at the same time next month.

at now next year

The job will start on the same date and at the same time next year.

at now next fri

The job will start at the same time next Friday.

at teatime

The job will run at 4 p.m. They keywords noon and midnight can also be used.

at 16:00 today

The job will run at 4 p.m. today.

at 16:00 tomorrow

The job will run at 4 p.m. tomorrow.

at 2:45pm

The job will run at 2:45 p.m. on the current day.

at 14:45

The job will run at 2:45 p.m. on the current day.

at 5:00 Sep 14 2003

The job will begin at 5 a.m. on September 14, 2003.

at 5:00 9/14/03

The job will begin at 5 a.m. on September 14, 2003.

Submitting scheduled jobs

The at facility offers a lot of flexibility in how you can submit scheduled jobs. There are three ways to submit a job to the at facility:

  • Piped in from standard input.???For example, the following command will attempt to build the Perl distribution from source in the early morning hours while the machine is likely to be less busy:

    echo "cd /tmp/perl; make ; ls -al" | at 2am tomorrow

    An ancillary benefit to this procedure is that a full log of the compilation process will be e-mailed to the user that submitted the job.

  • Read as standard input.???If no command is specified, at will prompt you to enter commands at the special at> prompt, as shown in the following example. You must indicate the end of the commands by pressing Ctrl+D, which signals an End of Transmission (<EOT>) to at.

    $ at 23:40
    at> cd /tmp/perl
    at> make
    at> ls -al
    at> <Ctrl-d>
  • Read from a file.???When the -f command-line option is followed by a valid filename, the contents of that file are used as the commands to be executed, as in the following example:

    $ at -f /root/bin/runme now + 5 hours

    This runs the commands stored in /root/bin/runme in five hours. The file can either be a simple list of commands or a shell script to be run in its own subshell (that is, the file begins with #!/bin/bash or the name of another shell).

Viewing scheduled jobs

You can use the atq command (effectively the same as at -l) to view a list of your pending jobs in the at queue, showing each job's sequence number, the date and time the job is scheduled to run, and the queue in which the job is being run.

The two most common queue names are "a," which represents the at queue, and "b," which represents the batch queue. All other letters (upper- and lowercase) can be used to specify queues with lower priority levels. If the atq command lists a queue name as =, it indicates that the job is currently running. Here is an example of output from the atq command:

# atq
2    2003-09-02 00:51 a
3    2003-09-02 00:52 a
4    2003-09-05 23:52 a

Here you can see that there are three at jobs pending (job numbers 2, 3, and 4, all indicated as "a"). After the job number, the output shows the date and hour each job is scheduled to run.

Deleting scheduled jobs

If you decide that you'd like to cancel a particular job, you can use the atrm command (equivalent to at -d) with the job number (or more than one) as reported by the atq command. For example, using the following output from atq:

# atq
18      2003-09-01 03:00 a
19      2003-09-29 05:27 a
20      2003-09-30 05:27 a
21      2003-09-14 00:01 a
22      2003-09-01 03:00 a

you can remove the jobs scheduled to run at 5:27 a.m. on September 29 and September 30 from the queue with the command atrm 19 20.

Using the batch command

If system resources are at a premium on your machine, or if the job you submit can run at a priority lower than normal, the batch command (equivalent to at -q b) may be useful. It is controlled by the same atd daemon, and it allows job submissions in the same format as at submissions (although the time specification is optional).

However, to prevent your job from usurping already scarce processing time, the job will run only if the system load average is below a particular value. The default value is 0.8, but specifying a command-line option to atd can modify this. This was used as an example in the earlier section describing start-up and shutdown. Here is an example of the batch command:

$ batch
at> du -h /home > /tmp/duhome
at> <Ctrl-d>

In this example, after I type the batch command, the at facility is invoked to enable me to enter the command(s) I want run. Typing the du -h /home > /tmp/duhome command line has the disk usages for everything in the /home directory structure output to the /tmp/duhome file. On the next line, pressing Ctrl+D ends the batch job. As soon as the load average is low enough, the command is run. (Run the top command to view the current load average.)

Using the cron facility

Another way to run commands unattended is via the cron facility. Part of the vixie-cron RPM package, cron addresses the need to run commands periodically or routinely (at least, more often than you'd care to manually enter them) and allows lots of flexibility in automating the execution of the command. As with the at facility, any output or error messages that haven't been redirected elsewhere are e-mailed to the user that submitted the job.

Also like the at facility, cron includes two access control files designed to limit which users can use it. The file /etc/cron.allow contains a list of users that are granted access, and the file /etc/cron.deny contains a similar list of those who may not submit cron jobs. If neither file exists, all users are granted access to cron.

There are four places where a job can be submitted for execution by the cron daemon crond:

  • The /var/spool/cron/username file.???This method, where each individual user (indicated by username) controls his or her own separate file, is the method used on UNIX System V systems.

  • The /etc/crontab file.???This is referred to as the system crontab file, and was the original crontab file from BSD UNIX and its derivatives. Only root has permission to modify this file.

  • The /etc/cron.d directory.???Files placed in this directory have the same format as the /etc/crontab file. Only root is permitted to create or modify files in this directory.

  • The /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly, and /etc/cron.monthly directories.???Each file in these directories is a shell script that runs at the times specified in the /etc/crontab file (by default at one minute after the hour, at 4:02 a.m. every day, Sunday at 4:22 a.m., and 4:42 a.m. on the first day of the month, respectively). Only root is allowed to create or modify files in these directories.

The standard format of an entry in the /var/spool/cron/username file consists of five fields specifying when the command should run: minute, hour, day of the month, month, and day of the week. The sixth field is the actual command to be run.

The files in the /etc/cron.d directory and the /etc/crontab file use the same first five fields to determine when the command should run. However, the sixth field represents the name of the user submitting the job (because it cannot be inferred by the name of the file as in a /var/spool/cron/username directory), and the seventh field is the command to be run. Table 12-7 lists the valid values for each field common to both types of files.

Table 12-7: Valid /etc/crontab Field Values

Field Number


Acceptable Values



Any integer between 0 and 59



Any integer between 0 and 23


day of the month

Any integer between 0 and 31



Any integer between 0 and 12, or an abbreviation for the name of the month (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec)


day of the week

Any integer between 0 and 7 (where both 0 and 7 can represent Sunday), or abbreviation for the day (Sun, Mon, Tue, Wed, Thu, Fri, Sat)

An asterisk (*) in any field indicates all possible values for that field. For example, an asterisk in the second column is equivalent to 0,1,2 . . . 22,23, and an asterisk in the fourth column means Jan,Feb,Mar . . . Nov,Dec. In addition, lists of values, ranges of values, and increments can be used. For example, to specify the days Monday, Wednesday, and Friday, the fifth field could be represented as the list Mon,Wed,Fri. To represent the normal working hours in a day, the range 9–5 could be specified in the second field. Another option is to use an increment, as in specifying 0–31/3 in the third field to represent every third day of the month, or */5 in the first field to denote every five minutes.

Lines beginning with a # character in any of the crontab-format files are comments, which can be very helpful in explaining what task each command is designed to perform. It is also possible to specify environment variables (in Bourne shell syntax, e.g., NAME="value") within the crontab file. Any variable can be specified to fine-tune the environment in which the job will run, but one that may be particularly useful is MAILTO. The following line will send the results of the cron job to a user other than the one that submitted the job:


If the following line appears in a crontab file, all output and error messages that haven't already been redirected will be discarded:


Modifying scheduled tasks with crontab

The files in /var/spool/cron should not be edited directly. They should only be accessed via the crontab command. To list the current contents of your own personal crontab file, type the following command:

$ crontab -l

All crontab entries can be removed with the following command:

$ crontab -r

Even if your personal crontab file doesn't exist, you can use the following command to begin editing it:

$ crontab -e

The file automatically opens in the text editor that is defined in your EDITOR or VISUAL environment variables, with vi as the default. When you're done, simply exit the editor. Provided there were no syntax errors, your crontab file will be installed. For example, if your user name is jsmith, you have just created the file /var/spool/cron/jsmith. If you add a line (with a descriptive comment, of course) to remove any old core files from your source code directories, that file may look similar to this:

# Find and remove core files from /home/jsmith/src
5 1 * * Sun,Wed find /home/jsmith/src -name core -exec rm {} \; > /dev/null 2>&1

The root user can access any user's individual crontab file by using the -u username option to the crontab command.

Understanding cron files

There are separate cron directories set up to contain cron jobs that run hourly, daily, weekly, and monthly. These cron jobs are all set up to run from the /etc/crontab file. The default /etc/crontab file looks like this:

# run-parts
01 * * * * root run-parts /etc/cron.hourly
02 4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly

The first four lines initialize the run-time environment for all subsequent jobs (the subshell in which jobs will run, the executable program search path, the recipient of output and error messages, and that user's home directory). The next five lines execute (as the user root) the run-parts program that controls programs that you may wish to run periodically.

run-parts is a shell script that takes a directory as a command-line argument. It then sequentially runs every program within that directory (shell scripts are most common, but binary executables and links are also evaluated). The default configuration executes programs in /etc/cron.hourly at one minute after every hour of every day; /etc/cron.daily at 4:02 a.m. every day; /etc/cron.weekly at 4:22 a.m. on Sundays; and /etc/cron.monthly at 4:42 a.m. on the first day of each month.

Here are examples of files that are installed in cron directories for different software packages:

  • /etc/cron.daily/logrotate.cron — Automates rotating, compressing, and manipulating system logfiles.

  • /etc/cron.daily/makewhatis.cron — Updates the whatis database (contains descriptions of man pages), which is used by the man -k, apropos, and whatis commands to find man pages related to a particular word.

  • /etc/cron.daily/slocate.cron — Updates the /var/lib/slocate/slocate.db database (using the updatedb command), which contains a searchable list of files on the machine.

  • /etc/cron.daily/tmpwatch — Removes files from /tmp, /var/tmp, and /var/catman that haven't been accessed in ten days.

  • /etc/cron.hourly/diskcheck — Checks available disk space on your hard drive each hour. Responds to low disk space based on settings in /etc/diskcheck.conf.

The makewhatis.cron script installed in /etc/cron.weekly is similar to the one in /etc/cron.daily, but it completely rebuilds the whatis database, rather than just updating the existing database.

Finally, in the /etc/cron.d directory are files that have the same format as /etc/crontab files.

Part IV: Red Hat Linux Network and Server Setup