Updated: 2017-01-20 00:48 EST

1 Introduction to delayed execution

There are two systems for running commands at later times and dates:

  1. The cron system that runs command lines repeatedly according to a schedule, and
  2. the at system that runs a set of commands once, at a later time.

2 Scheduling with the cron daemon and crontab

Unix/Linux has a program named cron that runs other programs at scheduled times, e.g. run a backup program every day at midnight. The cron runs both system programs, reading the /etc/crontab file, and personal cron programs, created by a separate crontab program.

A crontab file is a table of lines, each of which is a time specification (24-hour clock) followed by a command line to execute at that time, e.g.

34 13 * * * touch /var/log/mark    # touch at 1:34PM every day

Unix/Linux has both system (root-only) crontab files and personal user-level crontab files. The date/time specifications are the same for both types of crontab files. System crontab files have an extra userid field after the date/time specification; it will be described below.

The cron daemon examines and runs all crontab entries no more than once every minute. (The cron daemon can’t run anything more often than once a minute.)

If the system (or cron daemon) isn’t up and running at a scheduled time, the command is ignored and is not run. The system doesn’t magically run missed cron entries when the system is restarted. (There is a newer anacron system that can do that.)

The cron daemon is usually started as a service from a Run Level script when the system is booted, and it may not be configured to run in all Run Levels. The daemon produces log files that are usually kept under /var/log; the actual location will be determined by your syslog configuration settings.

2.1 The crontab time/date file format

A crontab is a text file of lines containing times and command lines. Each line starts with a five-field date/time specification. The five blank-separated time and date fields at the start of every crontab line are (from man 5 crontab):

crontab field allowed values
------------- --------------
minute        0-59
hour          0-23
day of month  1-31
month         1-12 (or names, if using a recent version of cron)
day of week   0-7 (0 or 7 is Sun, or use names)

Any field may be a list of numbers, separated by commas (no blanks allowed), or an asterisk (*) indicating “every” or “all”, or a range of two numbers separated by a dash:

00,30 01,13 * * * touch /tmp/foo    # touch every 30 minutes at 1am,1pm
00    08-11 * * * touch /tmp/foo    # touch every hour from 8am to 11am

The minimum resolution of the crontab is one minute, with some systems only running the crontab every 15 minutes.

See more time/date examples below under “Personal crontab Examples”.

2.2 The crontab command line format and current directory

The command line in a crontab file is any (non-interactive) shell command line. (Don’t try to run an interactive program such as the vim text editor or a GUI program such as Firefox!)

The current working directory of the shell when it runs the personal crontab command line is always your HOME directory, so if you use pathnames in your command line make sure the pathnames are valid relative to your own HOME directory:

* * * * * touch foo etc/bar # touch $HOME/foo and $HOME/etc/bar every minute

Lines that begin with # are comments inside crontab files. They are ignored.

2.3 Personal crontab files

Most Unix/Linux systems now allow individual users to have private crontab files for commands they want to run as themselves. Users must use the crontab command to manage their personal cron files. Changes take effect when the crontab command saves your personal crontab file and exits.

To edit your personal crontab file, the crontab command uses the text editor specified in the VISUAL or EDITOR environment variables:

$ crontab -l                         # show my personal crontab file
$ crontab -e                         # edit (or create) my crontab
$ crontab -r                         # delete my personal crontab

See man crontab – the crontab command for managing individual user crontab files.

On Ubuntu desktop systems such as the CLS, your selected editor for crontab -e is stored in the file ~/.selected_editor and can be changed with the command select-editor in many cases.

The current working directory of the shell when it runs the personal crontab command line is always your HOME directory, not the directory you were in when you ran the crontab command.

2.4 Personal crontab Examples

Below are some examples of personal crontab entries:

*  *  *  *  *  echo "every minute of every day of every month"
30 *  *  *  *  echo "30 minutes after every hour of every day of every month"
30 14 *  *  *  echo "at 14:30 every day of every month"
30 14 15 *  *  echo "at 14:30 on day 15 of every month"
30 14 15 10 *  echo "at 14:30 on day 15 of month 10 (October)"
30 14 *  *  6  echo "at 14:30 every Saturday"
30 0,8,16 * * * echo "at 00:30, 08:30, and 16:30 every day of every month"

Below is an example (a very long line) that sends the current Ottawa temperature to a cell phone every hour. This requires the elinks package and some form of mail or mailx package to be installed and configured to send Internet email. (To find your phone gateway, try http://www.notepage.net/smtp.htm.)

01 * * * * elinks -dump -no-numbering -no-references 'http://weather.gc.ca/rss/city/on-118_e.xml' | fgrep 'Temperature:' | mail -s "Temperature" 6135551212@msg.example.com

See man 5 crontab – (manual section 5) the format of the crontab files (personal and system).

The current working directory of the shell when it runs the personal crontab command line is your HOME directory.

2.5 The System /etc/crontab File

There is a system cron configuration file /etc/crontab that can run scheduled commands as any userid (usually as root). You can (as root) use a text editor to edit the system /etc/crontab file. Changes take effect as soon as the file is saved.

Modern Unix/Linux systems also have a directory of individual system crontab files under /est/cron.d/ and some standard directories for command scripts that you want to run at regular intervals, e.g. /etc/cron.daily, /etc/cron.hourly, etc.

2.6 Running as another userid in the system crontab

Unlike personal crontab files, the system crontab command lines are prefixed by a userid field that tells which user to use to run the commands. The usual user is root:

* * * * * root      touch /var/log/file   # run as root user
* * * * * syslog    touch /var/adm/file   # run as syslog user
* * * * * www-admin touch /var/http/file  # run as www-admin user

The system crontab file /etc/crontab needs a userid field at the start of each command line to know as which user to run the cron job. The personal crontab file does not contain a leading userid field, since you can only run jobs as your own userid:

# example line from the system crontab file /etc/crontab (root userid):
17 * * * * root cd / && run-parts --report /etc/cron.hourly

# example line from a personal (non-root) crontab file (no userid):
34 12 * * * echo "It's 12:34 and time to eat lunch" | write idallen

The userid field in a system crontab file comes after the time specification and before the text of the command line to run. It is only used in system crontab files, never in personal crontab files.

Unlike the system crontab file /etc/crontab, lines in personal crontab files do not start with a leading userid field.

The current working directory of the shell when the cron runs the system crontab command line is the HOME directory of the userid running the command. Most system crontab lines run as the root user.

3 The at command – run once

If you want to schedule some commands to happen just once at some time in the future, use the at command.

The at command is followed by a time or a time and a day or date. If you give both a date and a time, the date must follow the time (RTFM).

The program will prompt you for input. Enter the commands you want to run as standard input, one per line, then signal EOF:

$ date
Tue Nov 19 12:00:10 EST 2013

$ at 17:00
at> echo "Time to go home" | mail -s "Home Reminder" idallen
at> ^D
job 123 at Tue Nov 19 17:00:00 2013

$ at 12:00 friday
at> echo "lunch with Richard and Linus" | mail -s "Lunch Date" idallen
at> ^D
job 124 at Fri Nov 22 12:00:00 2013

$ at 00:01 jan 1
at> echo "Happy New Year" | mail -s "Auld Lang Syne" idallen
at> ^D
job 125 at Wed Jan  1 00:01:00 2014

The command accepts a wide range of time and date formats; see the man page for at. Note that dates must follow times, as shown above.

The standard error and standard output from your commands, if any, will be sent to you by email when the job finishes. See below for how to read your email.

If the system (or at daemon) isn’t up and running at the scheduled time that the at job would run, the scheduled command will be saved and run as soon as the system starts. (Unlike cron, which will not run missed events in the past.)

You can use the atq command to display the list (“queue”) of pending jobs to be run. You can use at -c 123 to see the actual queued job commands for job 123. (Since your entire environment is prefixed to each at job, you might use the tail command to see only the last few lines of the queued job.) You can cancel (“remove”) a scheduled job using atrm:

$ atq
123   Wed Dec  5 12:00:00 2013 a idallen

$ at -c 123 | tail
[... see the last 10 lines of your queued job number 123 here ...]

$ atrm 123                       # remove job 123

$ atq                            # show the queue of scheduled jobs

Since at jobs run only once, there is no table of jobs similar to a crontab. Use the atq command.

Unlike personal crontab jobs, which always have a current working directory of your HOME directory when they run, the at command jobs run using the current working directory in effect when the at job was queued, so relative pathnames in at jobs are relative to the same directory in which you created the at job:

$ pwd
$ at dec 1
at> touch foo                   # this will touch /tmp/foo not $HOME/foo
at> ^D
job 105 at Sun Dec  1 09:15:00 2013

4 Reading email from cron and at jobs

Since both cron and at jobs run at times when you may not be logged in, any standard output and standard error output from the jobs is collected and sent to your account email inbox via EMail.

The Course Linux Server has a very basic EMail client installed for reading (and sending) text-only EMail messages.

You can read about it in the section EMail on the CLS in the Course Linux Server web page.

| Ian! D. Allen, BA, MMath  -  idallen@idallen.ca  -  Ottawa, Ontario, Canada
| Home Page: http://idallen.com/   Contact Improv: http://contactimprov.ca/
| College professor (Free/Libre GNU+Linux) at: http://teaching.idallen.com/
| Defend digital freedom:  http://eff.org/  and have fun:  http://fools.ca/

Plain Text - plain text version of this page in Pandoc Markdown format

Campaign for non-browser-specific HTML   Valid XHTML 1.0 Transitional   Valid CSS!   Creative Commons by nc sa 3.0   Hacker Ideals Emblem   Author Ian! D. Allen