I put a cronjob in /etc/cron.{hourly,daily,weekly,monthly} and it does not run and how can I troubleshoot it?

Posted on in Categories Cloud Computing, Howto, Open Source, Web Developer last updated August 27, 2017

Recently 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 put a file (more like used the ln command to create a soft link ) in /etc/cron.hourly/ and it doesn’t run. There was no error in systemd log or cron log. Why is my cron job was not working, and here is how I 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.
Why is my crontab not working, and how do I troubleshoot it on Linux?
Cron is one of the most useful tool in a Linux or UNIX like operating systems. It is usually used for sysadmin jobs such as backups or cleaning /tmp/ directories and more.

Files under /etc/cron.{hourly,daily,weekly,monthly}

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 you must set permission:
$ sudo chmod +x /etc/cron.hourly/backup.sh
$ sudo 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 I had to rename my script using the mv command
$ sudo mv -v /etc/cron.hourly/backup.sh /etc/cron.hourly/backup
OR
$ sudo mv -v /root/scripts/backup.sh /root/scripts/backup<

Make sure the file has execute permissions

Use the chmod command:
$ sudo 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 your 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. You can also use systemctl command to view last few entries. This page tell you all 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.

Another day, another sysadmin problem solved.

Posted by: Vivek Gite

The author is the creator of nixCraft and a seasoned sysadmin and a trainer for the Linux operating system/Unix shell scripting. He has worked with global clients and in various industries, including IT, education, defense and space research, and the nonprofit sector. Follow him on Twitter, Facebook, Google+.

Leave a Comment