cron is a Unix daemon that allows users to schedule programs to run at set intervals. A crontab is the file that cron uses to determine what actions to perform and when. A cronjob is a the specific line (or job) in the crontab. The Toolserver provides a version of cron called cronie, which is more featureful than Solaris' built-in cron, and will be described here. For information on Solaris cron, refer to the crontab(1) manual page.
For more information on cronie, refer to cronie(1).
On the Toolserver, we strongly recommend that cron be used in conjunction with batch job scheduling. This page explains how to do this.
crontab has three basic commands:
- $ crontab -e
- edits (or creates) your current crontab in a text editor
- $ crontab -l
- displays your crontab
- $ crontab -r
- removes your crontab entirely
You can change the text editor used for editing the crontab in your environment.
Each line in the crontab file is a single cron job. The line contains five fields at the start indicating when the job should run, and the rest of the line is the command.
| hour (0-23),
| | day of the month (1-31),
| | | month of the year (1-12),
| | | | day of the week (0-6 with 0=Sunday).
| | | | | commands
30 2 * * 0,6 /some/command/to/run
30 2 * * 1-5 /another/command/to/run >/dev/null
Use "*" to mean "every"; for example, "30 2 * * *" runs the program at 02:30 UTC, every day of every month. Only specify "day of month" or "day of week", not both.
On Linux, you can write "*/x" to mean "every x". For example, writing "*/10" in the "minute" column means "every ten minutes".
The crontab file must end with a blank line (that is, the last character of the final line in the file must be a newline character). Many editors, like nano (the default editor) and vi do this by default. The "joe" editor does not do this - be sure to end your file with a blank line every time. If you don't, you won't receive an error message, but nothing will happen at the scheduled time.
An example which would run every hour of the day would be:
0 * * * * php $HOME/scripts/myscript.php
This means every hour, i.e. *, at minute 0. There is no need to write */1 for the hour field, as */1 is identical to *.
Lines beginning with a # will be treated as comments, and ignored, along with blank lines.
Using cron with batch job scheduling
We recommend that all tools be run as batch jobs, which has several advantages over standard jobs (for example, jobs will be automatically started on a suitably idle host instead of always running on the same host). To run jobs this way, start them with the cronsub command:
0 * * * * cronsub -s myscript % php $HOME/scripts/myscript.php
The second argument, "myscript", is the name of the job. This should be different for each job. The % should separate the cronsub command from the actual command to be run.
Note that jobs run this way will behave slightly differently, for example job output will be written to a file, $HOME/myscript.out, instead of being mailed to you. For more information, see Job scheduling#Running jobs from cron.
Note: these are non-portable and only work on Vixie-based crons.
@yearly Run once a year, "0 0 1 1 *".
@annually (same as @yearly)
@monthly Run once a month, "0 0 1 * *".
@weekly Run once a week, "0 0 * * 0".
@daily Run once a day, "0 0 * * *".
@midnight (same as @daily)
@hourly Run once an hour, "0 * * * *".
Cron will email you every time a command produces output. To avoid this, you can redirect the output to a file, or discard it.
>/dev/null on the command redirects normal output to nowhere. This will still email you error messages; you can avoid that by appending
2>&1, which sends fd 2 (stderr, i.e. error messages) to the same place as 1 (stdout, i.e. normal output). If you want those to go elsewhere, then specify that instead of
&1, for example:
#Redirect normal output to nowhere
0 * * * * php $HOME/scripts/myscript.php >/dev/null
You can also change the address to which cron will send output by writing a MAILTO line in your crontab:
Alternatively, put an email in
~/.forward. Multi-maintainer projects may wish to put one email per line for all members (using your
@toolserver.org email is allowed, it will be forwarded according to the
~/.forward file in the user's own account).
Cronie and Cronietab
- See also Job scheduling#submit.toolserver.org
To avoid a conflict with the system cron, the cronie crontab command is called
'cronie'. To convert your current crontab to a cronietab, you can use a
command like this:
$ crontab -l >crontab # list existing crontab to file
$ cronie crontab # install same as a cronietab
$ crontab -r # remove old crontab
You should probably use either crontab or cronie, but not both, since that could be confusing.
Timing and work load
Since a lot of users want to run all their cron jobs, it is useful to properly balance the load (as far as possible). E.g. using cron-lines like the following can cause high load:
0 0 * * * DoSomething
0 * * * * DoSomething
In a ideal world that would be no problem, but in real world that can be a problem. Why? Because many users have the same idea and - until some time ago - our submit-hosts simply failed then with
(CRON) CAN'T FORK (child_process): Not enough space.
DaB patched cronie (vixie cron) on the TS in order to store such jobs in a queue now, hold them back and execute as soon as possible - thus no jobs are lost - but they can become delayed!
Of course we could just correct the problem by buying new hardware, but these hosts are idle for most of the day anyway, as you can see from cron jobs sh.
So how to solve this problem? It's easy: Spread the load. Most times, it is not critical for a task (like a bot) to start exactly on time. So choose a minute other than 0 and divisible by 5. If it really does not matter when your task starts, then take the position of the first letter of your user-name and add 2, e.g.
"dab" → "d" → 4 → 6
Just to be clear: if your task really needs to start at minute 0 (or at midnight): do it. And of course a cron-task can fail for other reasons too, so contact an admin (jira-bug preferred) if you have a problem.