Linux tip

Job scheduling with cron and at

How to enjoy life while your system works

Content series:

This content is part # of # in the series: Linux tip

Stay tuned for additional content in this series.

This content is part of the series:Linux tip

Stay tuned for additional content in this series.

Linux® and UNIX® systems allow you to schedule jobs in the future, either just once, or on a recurring schedule. This article, excerpted from the developerWorks tutorial LPI exam 102 prep: Administrative tasks, shows you how to schedule jobs periodically, and how to run a job at some future time.

Many administrative tasks must be done frequently and regularly on a Linux system. These include rotating log files so filesystems do not become full, backing up data, and connecting to a time server to keep your system time synchronized. See the full tutorial mentioned above for more about these administrative tasks. In this tip, you learn about the scheduling facilities available in Linux using the cron and anacron facilities and the crontab and at commands. Even if your system sleeps or is turned off, anacron can help it catch up the next time it is awake.

Run jobs at regular intervals

Running jobs at regular intervals is managed by the cron facility, which consists of the crond daemon and a set of tables describing what work is to be done and with what frequency. The daemon wakes up every minute and checks the crontabs to determine what needs to be done. Users manage crontabs using the crontab command. The crond daemon is usually started by the init process at system startup.

To keep things simple, let's suppose that you want to run the command shown in Listing 1 on a regular basis. This command doesn't actually do anything except report the day and the time, but it illustrates how to use crontab to set up cron jobs, and we'll know when it was run from the output. Setting up crontab entries requires a string with escaped shell metacharacters, so it is best done with simple commands and parameters. In this example, the echo command will be run from within a script /home/ian/, which takes no parameters. This saves some careful work with escape characters.

Listing 1. A simple command example
[ian@lyrebird ~]$ cat
 echo "It is now $(date +%T) on $(date +%A)"
[ian@lyrebird ~]$ ./
It is now 18:37:42 on Friday

Creating a crontab

To create a crontab, you use the crontab command with the -e (for "edit") option. This opens the vi editor unless you have specified another editor in the EDITOR or VISUAL environment variable.

Each crontab entry contains six fields:

  1. Minute
  2. Hour
  3. Day of the month
  4. Month of the year
  5. Day of the week
  6. String to be executed by sh

Minutes and hours range from 0-59 and 0-23, respectively, while day of month and month of year range from 1-31 and 1-12, respectively. Day of week ranges from 0-6, with 0 being Sunday. Day of week may also be specified as sun, mon, tue, and so on. The sixth field is everything after the fifth field, and is interpreted as a string to pass to sh. A percent sign (%) is translated to a newline, so if you want a % or any other special character, precede it with a backslash (\). The line up to the first % is passed to the shell, while any line(s) after the % are passed as standard input.

The various time-related fields can specify an individual value, a range of values, such as 0-10 or sun-wed, or a comma-separated list of individual values and ranges. A somewhat artificial crontab entry for our example command might look like the example in Listing 2.

Listing 2. A simple crontab example
0,20,40 22-23 * 7 fri-sat /home/ian/

In this example, our command is executed at the 0th, 20th, and 40th minutes (every 20 minutes), for the hours between 10 P.M. and midnight on Fridays and Saturdays during July. See the man page for crontab(5) for details on additional ways to specify times.

What about the output?

You may be wondering what happens to any output from the command. Most commands designed for use with the cron facility will log output using the syslog facility that is discussed in the tutorial LPI exam 102 prep: Administrative tasks. However, any output that is directed to stdout will be mailed to the user. Listing 3 shows the output you might receive from our example command.

Listing 3. Mailed cron output
From  Fri Jul  6 23:00:02 2007
Date: Fri, 6 Jul 2007 23:00:01 -0400
From: (Cron Daemon)
Subject: Cron <ian@lyrebird> /home/ian/
Content-Type: text/plain; charset=UTF-8
Auto-Submitted: auto-generated
X-Cron-Env: <SHELL=/bin/sh>
X-Cron-Env: <HOME=/home/ian>
X-Cron-Env: <PATH=/usr/bin:/bin>
X-Cron-Env: <LOGNAME=ian>
X-Cron-Env: <USER=ian>

It is now 23:00:01 on Friday

Where is my crontab?

The crontab that you created with the crontab command is stored in /etc/spool/cron under the name of the user who created it. So the above crontab is stored in /etc/spool/cron/ian. Given this, you will not be surprised to learn that the crontab command, like the passwd command, is an suid program that runs with root authority.


In addition to the user crontab files in /var/spool/cron, cron also checks /etc/crontab and files in the /etc/cron.d directory. These system crontabs have one additional field between the fifth time entry (day) and the command. This additional field specifies the user for whom the command should be run, normally root. A /etc/crontab might look like the example in Listing 4.

Listing 4. /etc/crontab

# 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

In this example, the real work is done by the run-parts command, which runs scripts from /etc/cron.hourly, /etc/cron.daily, and so on; /etc/crontab simply controls the timing of the recurring jobs. Note that the commands here all run as root. Note also that the crontab can include shell variables assignments that will be set before the commands are run.


The cron facility works well for systems that run continuously. For systems that may be turned off much of the time, such as laptops, another facility, the anacron (for "anachronistic cron") can handle scheduling of the jobs usually done daily, weekly, or monthly by the cron facility. Anacron does not handle hourly jobs.

Anacron keeps timestamp files in /var/spool/anacron to record when jobs are run. When anacron runs, it checks to see if the required number of days has passed since the job was last run and runs it if necessary. The table of jobs for anacron is stored in /etc/anacrontab, which has a slightly different format from /etc/crontab. As with /etc/crontab, /etc/anacrontab may contain environment settings. Each job has four fields:

  1. period
  2. delay
  3. job-identifier
  4. command

The period is a number of days, but may be specified as @monthly to ensure that a job runs only once per month, regardless of the number of days in the month. The delay is the number of minutes to wait after the job is due to run before actually starting it. You can use this to prevent a flood of jobs when a system first starts. The job identifier can contain any non-blank character except slashes (/).

Both /etc/crontab and /etc/anacrontab are updated by direct editing. You do not use the crontab command to update these files or files in the /etc/cron.d directory.

Run jobs at specific times

Sometimes you may need to run a job just once, rather than regularly. For this you use the at command. The commands to be run are read from a file specified with the -f option, or from stdin if -f is not used. The -m option sends mail to the user even if there is no stdout from the command. The -v option displays the time at which the job will run before reading the job. The time is also displayed in the output.

Listing 5 shows an example of running the script that you used earlier. Listing 6 shows the output that is mailed back to the user after the job runs. Notice that it is somewhat more compact than the corresponding output from the cron job.

Listing 5. Using the at command
[ian@lyrebird ~]$ at -f -v 10:25
Sat Jul  7 10:25:00 2007

job 5 at Sat Jul  7 10:25:00 2007
Listing 6. Job output from at
From  Sat Jul  7 10:25:00 2007
Date: Sat, 7 Jul 2007 10:25:00 -0400
From: Ian Shields <>
Subject: Output from your job        5

It is now 10:25:00 on Saturday

Time specifications can be quite complex. Listing 7 shows a few examples. See the man page for at or the file /usr/share/doc/at/timespec or a file such as /usr/share/doc/at-3.1.10/timespec, where 3.1.10 in this example is the version of the at package.

Listing 7. Time values with the at command
[ian@lyrebird ~]$ at -f  10pm tomorrow
job 14 at Sun Jul  8 22:00:00 2007
[ian@lyrebird ~]$ at -f 2:00 tuesday
job 15 at Tue Jul 10 02:00:00 2007
[ian@lyrebird ~]$ at -f 2:00 july 11
job 16 at Wed Jul 11 02:00:00 2007
[ian@lyrebird ~]$ at -f 2:00 next week
job 17 at Sat Jul 14 02:00:00 2007

The at command also has a -q option. Increasing the queue increases the nice value for the job. There is also a batch command, which is similar to the at command except that jobs are run only when the system load is low enough. See the man pages for more details on these features.

Manage scheduled jobs

Listing scheduled jobs

You can manage your cron and at jobs. Use the crontab command with the -l option to list your crontab, and use the atq command to display the jobs you have queued using the at command, as shown in Listing 8.

Listing 8. Displaying scheduled jobs
[ian@lyrebird ~]$ crontab -l
0,20,40 22-23 * 7 fri-sat /home/ian/
[ian@lyrebird ~]$ atq
16      Wed Jul 11 02:00:00 2007 a ian
17      Sat Jul 14 02:00:00 2007 a ian
14      Sun Jul  8 22:00:00 2007 a ian
15      Tue Jul 10 02:00:00 2007 a ian

If you want to review the actual command scheduled for execution by at, you can use the at command with the -c option and the job number. You will notice that most of the environment that was active at the time the at command was issued is saved with the scheduled job. Listing 9 shows part of the output for job 15 from Listings 7 and 8. .

Listing 9. Using at -c with a job number
# atrun uid=500 gid=500
# mail ian 0
umask 2; export HOSTNAME
SHELL=/bin/bash; export SHELL
SSH_CLIENT=\ 3210\ 22; export SSH_CLIENT
SSH_TTY=/dev/pts/5; export SSH_TTY
USER=ian; export USER
HOME=/home/ian; export HOME
cd /home/ian || {
         echo 'Execution directory inaccessible' >&2
         exit 1
${SHELL:-/bin/sh} << `(dd if=/dev/urandom count=200 bs=1 \
   2>/dev/null|LC_ALL=C tr -d -c '[:alnum:]')`

 echo "It is now $(date +%T) on $(date +%A)"

Note that the contents of our script file have been copied in as a here-document that will be executed by the shell specified by the SHELL variable or /bin/sh if the SHELL variable is not set. See the tutorials LPI exam 101 prep, Topic 103: GNU and UNIX commands if you need to review here-documents.

Deleting scheduled jobs

You can delete all scheduled cron jobs using the cron command with the -r option as illustrated in Listing 10.

Listing 10. Displaying and deleting cron jobs
[ian@lyrebird ~]$ crontab -l
0,20,40 22-23 * 7 fri-sat /home/ian/
[ian@lyrebird ~]$ crontab -r
[ian@lyrebird ~]$ crontab -l
no crontab for ian

To delete system cron or anacron jobs, edit /etc/crontab, /etc/anacrontab, or edit or delete files in the /etc/cron.d directory.

You can delete one or more jobs that were scheduled with the at command by using the atrm command with the job number. Multiple jobs should be separated by spaces. Listing 11 shows an example.

Listing 11. Displaying and removing jobs with atq and atrm
[ian@lyrebird ~]$ atq
16      Wed Jul 11 02:00:00 2007 a ian
17      Sat Jul 14 02:00:00 2007 a ian
14      Sun Jul  8 22:00:00 2007 a ian
15      Tue Jul 10 02:00:00 2007 a ian
[ian@lyrebird ~]$ atrm 16 14 15
[ian@lyrebird ~]$ atq
17      Sat Jul 14 02:00:00 2007 a ian

Configure user access to job scheduling

If the file /etc/cron.allow exists, any non-root user must be listed in it in order to use crontab and the cron facility. If /etc/cron.allow does not exist, but /etc/cron.deny does exist, a non-root user who is listed in it cannot use crontab or the cron facility. If neither of these files exists, only the super user will be allowed to use this command. An empty /etc/cron.deny file allows all users to use the cron facility and is the default.

The corresponding /etc/at.allow and /etc/at.deny files have similar effects for the at facility.

Learn more

If you'd like to know more about administrative tasks in Linux, read the tutorial "LPI exam 102 prep: Administrative tasks," from which this article was excerpted, or see the other Related topics below. Don't forget to rate this page.

Downloadable resources

Related topics

Zone=Linux, AIX and UNIX, Open source
ArticleTitle=Linux tip: Job scheduling with cron and at