What is cron?
cron itself is a daemon, which means it is running but dormant until one of the scheduled times is hit. It is used to schedule events to run at a specified time.
The following is a narrated "What is cron?" video. It is hosted on YouTube, and features the cast of Team Fortress 2.
What does a cron look like?
Basic cron structure
* * * * * * user command/to/execute ┬ ┬ ┬ ┬ ┬ ┬ │ │ │ │ │ │ │ │ │ │ │ └ year (optional category) 1970-2099 │ │ │ │ └───── day of week (0 - 6 Sun - Sat) │ │ │ └────────── month (1 - 12) │ │ └─────────────── day of month (1 - 31) │ └──────────────────── hour (0 - 23) └───────────────────────── min (0 - 59)
|@reboot||Run once at startup||None|
|@yearly / @anually||Run one a year||0 0 1 1 *|
|@monthly||Run once a month||0 0 1 * *|
|@weekly||Run once a week||0 0 * * 0|
|@daily / @midnight||Run once a day||0 0 * * *|
|@hourly||Run once an hour||0 * * * *|
So a cron using a short cut may look like this:
@hourly /usr/local/bin/php /home/user/script.php
|Field||Allowed Values||Allowed Characters|
|Minutes||0-59||* / , -|
|Hours||0-23||* / , -|
|Day of Month||1-31||* / , - L W|
|Month||1-12 or jan - dec||* / , -|
|Day of Week||0-7 or sun-sat||* / , - L #|
|Year*||1970-2099||* / , -|
But what do they mean?
Asterisk ( * ) - Indicates that the cron expression matches for all values of the field.
Slash ( / ) - Describes increments of ranges. */5 **** is every 5 minutes
Comma ( , ) - Used to separate items of a list. Using "MON,FRI" in the 5th field (day of week) means Mondays and Fridays.
Hyphen ( - ) - Defines ranges. 2013-2015 indicates every year between 2013 and 2015.
L - stands for "last". When used in the day-of-week field, it allows you to specify constructs such as "the last Friday" ("5L") of a given month.
W - Allowed for the day-of-month field, W is used to specify the weekday nearest the given day.
Hash ( # ) - Allowed for the day-of-week field, and must be followed by a number between one and five. It allows you to specify "the first Monday" of a given month.
So a cron that runs on the last Friday of every month would look like this:
* * * * 5L /some/command
Where are crons found?
These look just like a regular entry from crontab but add the option to mail to and define the shell.
MAILTO= SHELL=/bin/bash */3 * * * * root /usr/local/sbin/bfd -q
Crons found in daily, hourly, monthly and weekly do not need any scheduling definitions added. Generally these are in the form of a script. There is a check that runs, if the cron has not fired within the specified time it will run the file.
Example: If /etc/cron.hourly/foo.pl has not run in the past 60 minutes when the check fires off, this script will be run.
You can edit this by using the crontab command or through the cPanel cron editor.
- -l list current crontab
- -r remove current crontab
- -e edit current crontab
- -u edit other users' crontabs (must be root or sudo; must be used with the other above flags)
Ex. crontab -u username -e
/etc/cron.deny and /etc/cron.allow
These files will restrict access to cron for the specified users
If this file exists the user MUST be listed here in order to run cronjobs.
This file is generally present on all servers. It by default lists nobody in its body. If you would like to allow crons for everyone on the server except for a specific user this file is going to be more friendly than the .allow file.
Troubleshooting Cron Problems
If a customer is complaining because their cron jobs are not working at the correct time, there is a chance that the system clock is not set correctly. Here are the steps for fixing this.
1. Check the date from command line.
[root@host ~]# date Fri May 16 09:57:12 EDT 2014
This will give you the date, time and time zone.
2. Compare the previous output with the settings in the php.ini file.
[root@host ~]# grep timezone /usr/local/lib/php.ini date.timezone="America/New_York"
Verify they are using the default php.ini file. If there are multiple, make sure the timezone is set in each one as required--------
3. Finally check the hardware clock. This is the equivalent of the bios clock in a standard PC. It is running independent of WHM.
[root@host ~]# hwclock Fri 16 May 2014 10:00:14 AM EDT -0.688859 seconds
4. If date and hwclock do not match, then there will be a discrepancy in the time that cron jobs run. Here is an example of that, it was causing the crons to be 2 hours off
root@host [/var/log]# date Fri May 9 11:33:10 MDT 2014 root@host [/var/log]# hwclock Fri 09 May 2014 05:33:16 PM MDT -0.640659 seconds
5. The fix is simple. First, follow the NTP wiki to update the system time. https://wiki.int.liquidweb.com/articles/NTP Next, run the following command.
root@host [/var/log]# hwclock --systohc
This will match the hwclock to the system clock.
You should now see the following output
root@host [/var/log]# date Fri May 9 12:00:42 MDT 2014 root@host [/var/log]# hwclock Fri 09 May 2014 12:00:50 PM MDT -0.203498 seconds
6. Watch the cron logs by running:
tail -f /var/log/cron
If the timestamps are still wrong there, try restarting rsyslog, ntpd, and then crond:
/etc/init.d/rsyslog restart; /etc/init.d/syslogd restart # Different cent versions use different variants on syslog, apparently. /etc/init.d/ntpd restart /etc/init.d/crond restart