Why are my cron jobs not running when expected?
Q: Why are my cron jobs (cron.daily, cron.weekly, cron.monthly) not running when I expect them to run? or at what times do cron.hourly, cron.daily, cron.weekly, cron.monthly jobs run?
A: Cron in newer versions of Linux may run
abit differently than in older versions.
(note: paths may not match your specific system these were the defaults for my OpenSuse10.3 install)
You may be used to seeing the following in the /etc/crontab file:
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
but now it looks something like this:
SHELL=/bin/sh PATH=/usr/bin:/usr/sbin:/sbin:/bin:/usr/lib/news/bin MAILTO=root # # check scripts in cron.hourly, cron.daily, cron.weekly, and cron.monthly # -*/15 * * * * root test -x /usr/lib/cron/run-crons && /usr/lib/cron/run-crons >/dev/null 2>&1
It will still run any scripts you have placed in /etc/cron.{hourly, daily, weekly, monthly} but it may not run them when you expect them to run. /usr/lib/cron/run-crons compares the current time to the /var/spool/cron/lastrun/cron.{time} file to determine if those jobs need to be run.
For hourly, it checks if the current time is greater than (or exactly) 60 minutes past the timestamp of the /var/spool/cron/lastrun/cron.hourly file.
For weekly, it checks if the current time is greater than (or exactly) 10080 minutes past the timestamp of the /var/spool/cron/lastrun/cron.weekly file.
Monthly uses a caclucation to check the time difference, but is the same type of check to see if it has been one month after the last run.
Daily has a couple variations available:
- By default it checks if it is more than or exactly 1440 minutes since lastrun.
- If DAILY_TIME is set in the /etc/sysconfig/cron file, then that is the time (within 15minutes) when daily will run.
- For systems that are powered off at DAILY_TIME, daily tasks will run at the DAILY_TIME, unless it has been more than x days, if it is, they run at the next running of run-crons. (default 7days, can set shorter time in /etc/sysconfig/cron.)
Because of these changes, the first time you place a job in one of the /etc/cron.{time} directories, it will run the next time run-crons runs, which is at every 15mins (xx:00, xx:15, xx:30, xx:45) and that time will be the lastrun, and become the normal schedule for future runs. Note that there is the potential that your schedules will begin drift by 15minute increments.
There are some ways to overcome these issues. One is to manually schedule your jobs with cron at specific times and not use the /etc/cron.{time} directories. Another is to make the following additions to the crontab file:
59 * * * * root rm -f /var/spool/cron/lastrun/cron.hourly 14 4 * * * root rm -f /var/spool/cron/lastrun/cron.daily 29 4 * * 6 root rm -f /var/spool/cron/lastrun/cron.weekly 44 4 1 * * root rm -f /var/spool/cron/lastrun/cron.monthly
Those changes will remove the lastrun files from the system at the scheduled times which will force run-crons to run the jobs on its next run.
You could also use the touch command on the lastrun file with a specific timestamp if you wanted to manually adjust the schedule.
Comments
There appears an issue if you try and schedule your daily to run around midnight using the DAILY_TIME option because of the script subtracting 15minutes to check if it should run. Best solution if you want daily to run at midnight is to not user Daily_time and instead use the rm cron options:
at:
59 23 * * * root rm -f /var/spool/cron/lastrun/cron.daily
that will insure the jobs in the cron.daily directory run at midnight.