Cron is the default scheduler in linux distributions. Here’s a couple of easy helpers
Background
Command | Description |
---|---|
crontab -e |
Open the Cron for the current user |
crontab -l |
List Cron tasks for the current user |
crontab -u username -l |
View the Cron tasks of another user |
Cron tasks are added by adding rows at the bottom of the crontab file using the following syntax
1 2 3 4 5 /path/to/command arg1 arg2
or
1 2 3 4 5 /path/to/script.sh
Where,
- Minute (0-59)
- Hours (0-23)
- Day (0-31)
- Month (0-12 [12 == December])
- Day of the week(0-7 [7 or 0 == sunday]) /path/to/command – Script or command name to schedule
* * * * * command to be executed
- - - - -
| | | | |
| | | | ----- Day of week (0 - 7) (Sunday=0 or 7)
| | | ------- Month (1 - 12)
| | --------- Day of month (1 - 31)
| ----------- Hour (0 - 23)
------------- Minute (0 - 59)
Each value can be made using
Syntax | Description |
---|---|
* |
any value |
, |
value list separator |
- |
range of values |
/ |
step values |
whitespace |
value separator |
Examples
syntax | result |
---|---|
0 * * * * |
“At minute 0” |
0 * * * * |
“Every 60 minutes” |
* * * * * |
“Every minute” |
*/2 * * * * |
Every 2 minutes |
1-59/2 * * * * |
Every 2nd minute, from 1 through 59 |
*/5 * * * * |
Every 5 minutes |
*/15 * * * * |
Every 15 minutes |
0 */2 * * * |
Every 2 hours, at zero past the hour |
0 0 * * * |
Every day at midnight |
0 9-18 * * * |
Every hour, at zero past the hour, between 9am and 6pm |
0 1 * * * |
Every day at 1am |
0 9 * * * |
Every morning (at 9am) |
0 0 * * SUN |
Every Sunday, just after midnight on Saturday |
0 0 * * MON |
Every Monday, just after midnight on Sunday |
0 0 * * TUE |
Every Tuesday, just after midnight on Monday |
0 0 * * WED |
Every Wednesday, just after midnight on Tuesday |
0 0 * * THU |
Every Thursday, just after midnight on Wednesday |
0 0 * * FRI |
Every Friday, just after midnight Thursday |
0 0 * * SAT |
Every Saturday, just after midnight Friday |
0 0 * * 1-5 |
Every weekday |
0 0 * * 0 |
Every week (On Sunday in this case) |
0 0 * * 6,0 |
Every Weekend day, both on Saturday and Sunday |
0 0 1 * * |
Every month, (on 1st day of the month in this case) |
0 0 1 */2 * |
Every 2nd month |
0 0 1 */6 * |
Every 6 months |
0 0 1 1 * |
Every year |
There are some alias helpers which are not universally supported
Syntax | Description |
---|---|
@yearly |
Yearly tasks |
@annually |
Annual tasks |
@monthly |
Monthly tasks |
@weekly |
Weekly tasks |
@daily |
Daily tasks |
@hourly |
Hourly tasks |
@reboot |
Upon reboot |
Cron with Seconds resolution
CRON has 60 second resolution, so to get sub minute events, you need to add a cron task more than once.
i.e. Every 30 seconds
* * * * * command
* * * * * sleep 30 && command
Cron location
Path | Description | Notes |
---|---|---|
/etc/cron.d |
Ad-hoc cron file can be placed here | |
/etc/crontab |
System level cron tasks | |
/etc/cron.hourly |
Hourly cron tasks | Must be root owner |
/etc/cron.daily |
Daily cron tasks | Must be root owner |
/etc/cron.weekly |
Weekly cron tasks | Must be root owner |
/etc/cron.monthly |
Monthly cron tasks | Must be root owner |
Troubleshooting
-
Checking Start
When a Cron task starts it is logged in the
syslog
found at/var/log/syslog
also accessible usingdmesg
for recent events only.A cron task executing a script such as
0 * * * * /path/to/script.sh
will appear in the log asscript.sh
, and as a result you can find the task executing using grep.grep <pattern> /var/log/syslog
which should list every time the pattern is matched in the syslog, and therefore listing every time cron started the task.i.e.
grep my_script.sh /var/log/syslog
-
Checking simultaneous execution
ps aux | grep <pattern>
can be used to show all current processes which match a pattern.i.e.
ps aux | grep my_script.sh
Sometimes it is worth adding this check into the Cron script to determine whether to bail out preventing multiple copies of a script to execute in parallel
Example:
*/2 * * * * /path/to/myscript.sh
#!/bin/sh if ps -ef | grep -v grep | grep doctype.php ; then exit 0 else /home/user/bin/doctype.php >> /home/user/bin/spooler.log & #mailing program /home/user/bin/simplemail.php "Print spooler was not running... Restarted." exit 0 fi
Another alternative to prevent multiple execution can be achieved via
flock
i.e.
* * * * * /usr/bin/flock -n /tmp/fcj.lockfile /usr/local/bin/frequent_cron_job
-
Logging Errors
42 1 * * * /path/to/real/job || echo $?
will write an error code to thesyslog
, if the first script fails/var/log/auth.log
records when authentication occurs, and can therefore be used to determine when processes such as the cron script starts and stops.A script which doesn’t report a consistent error already, can be corrected
- Add
set -e -u
to top of the script file, under the#!
line - Then change the cron task script to
sh -x main_script.sh || echo Cron task failed: $?
and note-x
causes each line to be printed out before it is executed - Then grep the syslog to find the task
grep 'Cron' /var/log/syslog
- Add