Why is my crontab not working?



So your crontab entry is failing and you don't know why. How do you proceed?

TLDR

  1. Does your crontab end with an empty line? It must or the last entry will not be considered.
  2. Have you forgotten to set your PATH variable?
  3. Have you setup logging and checked the output for errors?

Suggested Crontab Layout

# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow   command

MAILTO=""
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

54 4 * * * /root/cron/something.sh 2>&1 | /usr/bin/logger -t YourCustomTagHere
*/10 * * * * /root/cron/otherthing.sh 2>&1 | /usr/bin/logger -t AnotherCustomTagHere

# The crontab must end with an empty line

Start with these two lines

MAILTO=""
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

The first line makes sure that none of those annoying "mails" are getting sent. We will rather setup logging for each of our entries instead.

The second line sets a proper PATH variable. For some reason this is not done automatically and your crontab entry might fail because it can't find binaries you refer to. I came up with the PATH by logging in as some normal user and typing:

echo "${PATH}"

Make use of /usr/bin/logger

I suffix each and every of my crontab entries with something like this:

2>&1 | /usr/bin/logger -t YourCustomTagHere

This sets up logging for the crontab entry using syslog (https://serverfault.com/questions/137468/better-logging-for-cronjobs-send-cron-output-to-syslog). You can now find the recent log entries by typing:

grep "YourCustomTagHere" /var/log/syslog

End with empty line

Finally it's important that your crontab ends with an empty line or the last crontab entry will not be applied.

Helpful External Article

This StackOverflow question has an excellent step by step troubleshooting answer: https://stackoverflow.com/questions/22743548/cronjob-not-running