Why does the cronjob fail to run, and how to troubleshoot it
Cron allows Linux and Unix users to run commands or scripts at a given date and time. You can schedule scripts to be executed periodically. Cron is one of the most useful tools in a Linux or UNIX like operating systems. It is usually used for sysadmin jobs such as backups or cleaning /tmp/ directories and more.
Sometimes, when we set a cronjob in /etc/cron, it may not run. There will be no error in systemd log or cron log as well. So, let's see why the cronjob was not working, and how we can troubleshoot it.
As an example, I created a simple shell script called backup.sh in /root/scripts directory to just backup MySQL database and dumped it to /nfs/mysql/ directory. I have put a link of the file in /etc/cron.hourly/ and it doesn’t run.
Let's see how we can fix this.
Files under /etc/cron
The files under /etc/cron.d do not need to be executable, while, the files under /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly and /etc/cron.monthly do, as they are run by run-parts command. So we must set permission:
$ chmod +x /etc/cron.hourly/backup.sh
$ chmod +x /root/scripts/backup.sh
More about the run-parts
As the name suggests the run-parts command run scripts or programs in a directory such as /etc/cron.hourly/. However, it is very picky about file names. From the man page:
If neither the –lsbsysinit option nor the –regex option is given, then the names must consist entirely of ASCII upper- and lower-case letters, ASCII digits, ASCII underscores, and ASCII minus-hyphens.
If the –lsbsysinit option is given, then the names must not end in .dpkg-old or .dpkg-dist or .dpkg-new or .dpkg-tmp, and must belong to one or more of the following namespaces: the LANANA-assigned namespace (^[a-z0-9]+$); the LSB hierarchical and reserved namespaces (^_?([a-z0-9_.]+-)+[a-z0-9]+$); and the Debian cron script namespace (^[a-zA-Z0-9_-]+$).
If the –regex option is given, the names must match the custom extended regular expression specified as that option’s argument.
In short, the filename with an extension won’t run and are silently ignored by run-parts command. So we should rename the script using the mv command.
$ mv -v /etc/cron.hourly/backup.sh /etc/cron.hourly/backup
OR
$ mv -v /root/scripts/backup.sh /root/scripts/backup<
Make sure the file has execute permissions
Use the chmod command:
$ chmod +x /etc/cron.hourly/backup.sh
Set the path and Shebang
You must add the Shebang i.e. the character sequence consisting of the characters number sign and exclamation mark (#!):
#!/bin/sh
Also, add the path at the beginning of the script:
PATH=/path/1:/path/2
PATH=/sbin:/usr/sbin/:/usr/local/sbin:/bin:/usr/local/bin
Turn on crond log
By default installation, the cron jobs get logged to a file called /var/log/syslog. we can also use systemctl command to view the last few entries. Here, I have tried to tell you about the default cron log file and how to change or setup a cron.log file to contain just the cron job entries that show up in syslog.