Scheduling system tasks in Fedora 11 and RHEL

Solutions providers can learn how to schedule system tasks at specific times in Fedora 11 and Red Hat Enterprise Linux (RHEL) by learning to use the at, batch, and cron facilities.

Solutions provider takeaway:
Whether or not a task starts in exactly 60 seconds could make a huge impact on the level of service that you provide to customers, and it's up to solutions providers to ensure that users' tasks run on time.

Scheduling System Tasks

About the book:
This chapter excerpt on Automating System Tasks (download PDF) is taken from the Fedora 11 and Red Hat Enterprise Linux Bible. This book appeals to all types of Linux users and details the top ways to install and manage the newest version of Fedora and Red Hat Enterprise Linux (RHEL), including system administration, automating system tasks and dealing with security issues.

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 who 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 who 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. If you use either at.allow or at.deny, you aren't required to use both.

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 two 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 Apr 14 2008 The job will begin at 5 a.m. on April14, 2008.
at 5:00 4/14/08 The job will begin at 5 a.m. on April 14, 2008.

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 tobuild the Perl distribution from source in the early morning hours while the machine is likely to be less busy, assuming the perl sources are stored in /tmp/perl:
  • 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 who 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 ( ) to at.
  • $ at 23:40
    at> cd /tmp/perl
    at> make
    at> ls -al
  • Read from a file -- When the -fcommand-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 -1) 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 2008-09-02 00:51 a ericfj
3 2008-09-02 00:52 a ericfj
4 2008-09-05 23:52 a ericfj

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 2008-09-01 03:00 a ericfj
19 2008-09-29 05:27 a ericfj
20 2008-09-30 05:27 a ericfj
21 2008-09-14 00:01 a ericfj
22 2008-09-01 03:00 a ericfj

you can remove the jobs scheduled to run at 5:27 a.m. on September 29 and September 30 from the queue with the following 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 startup 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 to 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 cronie 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. (The cronie package contains an extended version of the cron utility for running scheduling tasks to run at a particular time, as well as adding security enhancements.)

As with the at facility, any output or error messages that haven't been redirected elsewhere are e-mailed to the user who submitted the job. Unlike using at, however, cron jobs are intended to run more than once and at a regular interval (even if that interval is only once per month or once per year).

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 who 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 (or if cron.deny is empty), 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 every 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 Field Acceptable Values
1 minute Any integer between 0 and 59
2 hour Any integer between 0 and 23, using a 24-hour clock
3 day of the month Any integer between 0 and 31
4 month 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)
5 day of the week Any integer between 0 and 7 (where both 0 and 7 can represent Sunday, 1 is Monday, 2 is Tuesday, and so on) or abbreviation for the day (Sun, Mon, Tue, Wed, Thu, Fri, Sat)

The latest version of cron (cronie and crontabs packages) includes the ability to indicate that a cron job be run at boot time.

Refer to the crontab man page (type man 5 crontab) for information on using the reboot option to have a command run once at startup time.


NOTE: The cronie package replaces the older vixie-cron.

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--17 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, for example, NAME="value") within the crontab file. Any variable can be specified to fine-tune the environment in which the job runs, but one that may be particularly useful is MAILTO. The following line sends the results of the cron job to a user other than the one who 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 -1

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.[0-9]* -exec rm {} ; >/dev/null 2>&1

Because core files in Fedora and RHEL consist of the word core, followed by a dot (.) and process ID, this example will match all files beginning with core. and followed by a number. The root user can access any user's individual crontab file by using the -u username option to the crontab command.

Understanding cron files

Separate cron directories are 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 is empty. Under the hood, though, cron runs the hourly, daily, weekly, and monthly jobs as if the 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 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 want 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 -- Automates rotating, compressing, andmanipulating 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/mlocate.cron--Updates the /var/lib/mlocate/mlocate.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.

About the author:
Christopher Negus spent several years working with UNIX operating system at the AT&T labs and in recent years has focused on Fedora and RHEL. His other Linux content includes the Linux Bible 2009 Edition: Boot up Ubuntu, Fedora, KNOPPIX, Debian, openSUSE, and more.

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.


NOTE: If you are not comfortable working with cron from the command line, there is a KCron Task Scheduler window that comes in the kdeadmin package for managing cron tasks. To launch KCron, type kcron from a Terminal window.


Shell scripts are an integral part of a Fedora or RHEL system for configuring, booting, administering, and customizing Fedora or RHEL. They are used to eliminate typing repetitive commands. They are frequently executed from the scheduling facilities within Fedora or RHEL, allowing much flexibility in determining when and how often a process should run. They also control the startup of most daemons and server processes at boot time.

The init daemon and its configuration file, /etc/inittab, also factor heavily in the initial startup of your Fedora or RHEL system. They implement the concept of run levels that is carried out by the shell scripts in /etc/rc.d/init.d, and they provide a means by which the machine can be shut down or rebooted in an orderly manner.

To have shell scripts configured to run on an ongoing basis, you can use the cron facility. Cron jobs can be added by editing cron files directly or by running commands such as at and batch to enter the commands to be run.

Automating System Tasks
  Fedora 11 and RHEL init scripts and processes
  Understanding run-level scripts in Fedora 11 and RHEL
  Scheduling system tasks in Fedora 11 and RHEL

Printed with permission from Wiley Publishing. Copyright 2009. Fedora 11 and Red Hat Enterprise Linux Bible by Christopher Negus. For more information about this title and other similar books, please visit

Dig Deeper on Operating Systems and Software Services