% Delayed and Repeated Scheduled Execution -- at, cron, crontab, and mail % Ian! D. Allen -- -- [www.idallen.com] % Fall 2016 - September to December 2016 - Updated 2018-10-29 18:50 EDT - [Course Home Page] - [Course Outline] - [All Weeks] - [Plain Text] 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. 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. 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".* 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. 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. 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 .) 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. - **Feature:** Use an [SMS Gateway List] to find the email address of your SMS enabled phone, and email a test message directly to your phone. (May be subject to length restrictions and incur an arbitrary delay.) - If the degree special character between the temperature number and the letter "C" doesn't display correctly on your phone (e.g. "10°C"), you can try adding either `-dump-charset latin1` or `-dump-charset ascii` to the `elinks` command line. - To find your phone gateway, try 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. ### 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. The System `/etc/cron.d` Directory ---------------------------------- Many Unix/Linux systems also have a directory of individual system `crontab` files under the `/etc/cron.d/` directory. Rather than editing and adding lines to the system `/etc/crontab`, put those lines in a file and put the file under `/etc/cron.d/` for automatic inclusion in the system `crontab`. Individual software packages can put their own files here without having to edit the main system `crontab` file. The System `/etc/cron.{daily,hourly,weekly,monthly}` Directories ---------------------------------------------------------------- Many Unix/Linux systems also have these directories: /etc/cron.daily/ /etc/cron.hourly/ /etc/cron.weekly/ /etc/cron.monthly/ As the names indicate, programs or scripts placed in these directories will be executed (by the system `crontab`) at at regular intervals, e.g. daily, hourly, weekly, or monthly. 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 /tmp $ 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 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 [www.idallen.com]: http://www.idallen.com/ [Course Home Page]: .. [Course Outline]: course_outline.pdf [All Weeks]: indexcgi.cgi [Plain Text]: 630_crontab_at_job_scheduler.txt [SMS Gateway List]: http://en.wikipedia.org/wiki/List_of_SMS_gateways [Course Linux Server]: 070_course_linux_server.html [EMail on the CLS]: 070_course_linux_server.html#email-on-the-cls [Pandoc Markdown]: http://johnmacfarlane.net/pandoc/