Crontab Basics
May 21, 2014
tl;dr
crontab -l # List crontab entries
crontab -e # Edit a crontab using the EDITOR specified (export EDITOR=nano)
crontab -r # Remove a crontab
sudo crontab -e # Edit root user’s crontab
crontab my-crontab # add cron jobs by giving a file to crontab
- If you are adding a script in any of the cron directories, it has to be executable
- Use absolute paths for files, directories and executable commands
- it should link to the absolute path of the executables (commands). e.g.
/bin/echoinstead ofecho. Find out absolute paths with thewhichcommand, e.g.which echo(or consider adding PATH at the top of the crontab file) - Commands that need to be run with
sudoshould be added to therootuser's crontab - Have your script create a file that log success or failure, makes it easier to troubleshoot cron
echo "Nightly Backup Successful: $(date)" >> /tmp/mybackup.log - Recommended is to add cron jobs to any of the cron directories (e.g.
/etc/cron.d) instead of editing a user's crontab (crontab -e) - The user adding the crons needs to be in
cron.allow(if it exists) - User access is determined by
/etc/cron.allowand/etc/cron.deny, if they exist. Blank/etc/cron.denymeans only root is allowed access, plus everyone who's in/etc/cron.allow. Nocron.allowandcron.denymeans everyone has access
Where to add your cron jobs?
There are plenty of places where you can place your cron jobs. You can
- edit the user's crontab
/var/spool/cron/crontabs/$USER-- not recommended,/var/spoolis considered temp/working directory, could wipe out with updates - edit
/etc/crontab-- This file could be used for other cron commands, but probably shouldn't be. It is not usual to add commands to this file. While an experienced user should know about it, it is not recommended that you add anything to /etc/crontab. Apart from anything else, this could cause a problem if the /etc/crontab file is affected by updates! - place a file in
/etc/cron.d-- This directory can contain crontab files. The directory is often used by packages, and the crontab files allow a user to be associated with the commands in them. This would not be affected by updates but is a well known location - place a file in
/etc/cron.hourly,/etc/cron.daily,/etc/cron.weekly, or/etc/cron.monthly
It is recommended to add individual scripts in the cron directories instead of editing the user's crontab, as it can get wiped when you update the cron package (link). A user's crontab is stored under the /var/spool dircetory, which is considered a temporary/working directory and is likely to get deleted during an update
See if a cron has run
Edits to a user's crontab and the cron jobs run are all logged by default to /var/log/syslog and that's the first place to check if things are not running as you expect.
# search the /var/log/syslog for 'CRON' or 'crontab'
#cat /var/log/syslog | grep cron
grep CRON /var/log/syslog
grep -i CRON /var/log/syslog # will show results for both CRON and crontab
Aug 15 06:17:01 amiranzur CRON[14961]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly)
By default cron will email you the output of any program it runs. Popular destinations for cron logs include /var/log/cron, /var/log/messages and /var/log/syslog
See if a user has access
- If
/etc/cron.allowfile exists, user must be in it in order to run crontab - If
/etc/cron.denyfile exists, user must NOT be in it in order to run crontab - No
cron.alloworcron.denyfiles exist in a standard Ubuntu install, so all users should have cron available by default, until one of those files is created. - If a blank
cron.denyfile has been created, that will change to the standard behavior users of other operating systems might expect: cron only available to root or users incron.allow.
Absolute paths
One major pitfall to cron is cron runs in an extremely limited shell environment, as a result a lot of variables aren't exported in to the environment, mainly
$PATH. Make sure you use all absolute paths to executable, including common functions likeecho,uptime,date, etc all need to use full paths (/bin/echo,/bin/date,/usr/bin/uptime). To determine the path to an executable, you can use the which command like so:which echo- this will show you the full path to that tool.
Or, you can expand root users PATH variable by putting the following line at the top of the root crontab file:
PATH=/usr/sbin:/usr/bin:/sbin:/bin
Emails and logging
- By default cron will email you the output of any program it runs. Default email address is
root@yourhost - You can use a
MAILTO=...line in the crontab file to have cron send email to a specific address, which should make it easier to grep the mailer daemon logs
MAILTO=my.offsite.email@example.org
00 15 * * * echo "Just testing if crond sends email"
-
You can set the cron to explicitly log output to a file by redirecting it (
> /var/log/myjob.log 2>&1will append all output to /var/log/myjob.log,2>&1indicates that the standard error (2>) is redirected to the same file descriptor that is pointed by standard output (&1).) You can also use&>>for the same purpose. -
&>>works in Bash whereas2>&1works in normal shell. -
You can specify the Shell in the crontab by adding
SHELL=/bin/bashin thecrontab -efile. It'll work for most but not all cron implemetations. -
If you're not getting emails than check the system logs. Popular locations are
/var/log/cron,/var/log/messagesand/var/log/syslog. Usegrepto get cron related stuff (cat /var/log/syslog | grep cron)
Examples
touch /etc/cron.daily/certbot
echo "
# Check and Renew Let's Encrypt SSLs
# run twice a day (12:15am, 12:15pm) as per recommendation
15 0,12 * * * root /usr/bin/certbot renew" > /etc/cron.daily/certbot
chmod +x /etc/cron.daily/certbot
Troubleshooting
- If you have recently changed the server's timezone then you might need to restart the cron server so it would evaluate the cron times in the proper timezone