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
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/mycrontab.sh, which takes no parameters.
This saves some careful work with escape characters.
Listing 1. A simple command example
[ian@lyrebird ~]$ cat mycrontest.sh #!/bin/bash echo "It is now $(date +%T) on $(date +%A)" [ian@lyrebird ~]$ ./mycrontest.sh 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:
- Minute
- Hour
- Day of the month
- Month of the year
- Day of the week
- 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/mycrontest.sh
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 ian@lyrebird.raleigh.ibm.com Fri Jul 6 23:00:02 2007 Date: Fri, 6 Jul 2007 23:00:01 -0400 From: root@lyrebird.raleigh.ibm.com (Cron Daemon) To: ian@lyrebird.raleigh.ibm.com Subject: Cron <ian@lyrebird> /home/ian/mycrontest.sh 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.
/etc/crontab
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
SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root HOME=/ # 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.
Anacron
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:
- period
- delay
- job-identifier
- 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 mycrontest.sh 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 mycrontest.sh -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 ian@lyrebird.raleigh.ibm.com Sat Jul 7 10:25:00 2007 Date: Sat, 7 Jul 2007 10:25:00 -0400 From: Ian Shields <ian@lyrebird.raleigh.ibm.com> Subject: Output from your job 5 To: ian@lyrebird.raleigh.ibm.com 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 mycrontest.sh 10pm tomorrow job 14 at Sun Jul 8 22:00:00 2007 [ian@lyrebird ~]$ at -f mycrontest.sh 2:00 tuesday job 15 at Tue Jul 10 02:00:00 2007 [ian@lyrebird ~]$ at -f mycrontest.sh 2:00 july 11 job 16 at Wed Jul 11 02:00:00 2007 [ian@lyrebird ~]$ at -f mycrontest.sh 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/mycrontest.sh [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
#!/bin/sh
# atrun uid=500 gid=500
# mail ian 0
umask 2
HOSTNAME=lyrebird.raleigh.ibm.com; export HOSTNAME
SHELL=/bin/bash; export SHELL
HISTSIZE=1000; export HISTSIZE
SSH_CLIENT=9.67.219.151\ 3210\ 22; export SSH_CLIENT
SSH_TTY=/dev/pts/5; export SSH_TTY
USER=ian; export USER
...
HOME=/home/ian; export HOME
LOGNAME=ian; export LOGNAME
...
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:]')`
#!/bin/bash
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/mycrontest.sh [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
- Review the tutorial "LPI exam 102 prep: Administrative tasks" (developerWorks, Jul 2007) for more information on other administrative tasks in Linux, including user administration, backups, system logs, and Network Time Protocol. It is part of a larger LPI exam prep tutorial series covering Linux fundamentals and preparing you for system administrator certification.
- The Linux Documentation Project has a variety of useful documents, especially its HOWTOs.
- With IBM trial software, available for download directly from developerWorks, build your next development project on Linux.
- Stay current with developerWorks technical events and Webcasts.