I have got some problem running a cron job. Although I’ve researched the usage of cron job earlier, I still cannot make my crob job run as expected.
I used crontab -e to add a new crob job as follows:
2 * * * * /mycronjob
I intended to run the cron job every 2 minutes(note that no username is specified because crontab -e add cron jobs that will be executed by the current user). But nothing happened after I added the cron job. I followed the instructions to debug the problem.
First you should note the notations: cron, crontab, and crond. The mechanism to run tasks at specified time is called cron. The command used to add/edit a cron job is crontab, the daemon to check all crob jobs and start the specified programs is crond. I used “pgrep con” and “service crond status” to verify the cron daemon was indeed running.
I checked the permission of the command file mycronjob and found it is not executable. This might be the reason that prevented the cron job from running. I granted the execution privilege to that file using “chmod u+x /mycronjob” hoping this could solve the problem. However the cron job still could not run.
Finally I noticed the syntax of the cron file. The cron file format is correct but it is not my expected behavior. What I typed in the cron file is to execute the cron job at the second minute of every hour, every day. To specify an interval to run a command, you should use the following code:
*/2 * * * * /mycronjob
The notation is very confusing and not supported by all OS. It is almost as hard to remember as the command “chmod u+x file” which is used to add the execution privilege to the owner(user) himself while “chmod o+x file” used to add execution privilege to others.
Now I can see the cron job is executed every minute. But that is not the whole story. The cron job is used to restart the mysqld if it is dead. But it does not work as expected. The mysqld never gets restarted after it dies.
How to debug problems in a cron job? Note that the output of the cron script will not echo on the current console, so you should not expect to use the echo command to debug problems in a cron job. Instead you should use “echo
command 2>&1 >> logfile” to log the output of suspected commands in the cron job. For my script, I used ” echo
service mysqld restart 2>&1 >> logfile” to check if the service command was executed successfully. By checking the log file, I saw the following error:”/mycronjob.sh: line 10: service: command not found”. This is because cron uses a different set of environment variables to run the script. Specifically the PATH variables when running the cron job is not the same as the current PATH. To get the environment variables cron uses to run your script, you can add a cronjob to call env to print the environment variables to a file, then check the content of that file(reference). On my system, the content of the PATH environment variable is “PATH=/usr/bin:/bin”. So, I have to use the absolute path to specify the command name in my script., i.e.,”echo
/sbin/service mysqld restart 2>&1 >> logfile”. Fortunately, some common commands such as sed, awk, ps are in /usr/bin, so you do not need to specify the absolute path to use those commands in your script.
You can see debugging crontab is not easy. In this post, you can find strategic ways to debug cron job problems. In summary, to debug problems about your cron jobs, you can:
- check your email. Crond will send an email when it executes a cronjob. The email contains the output of the command of the cron job. In normal suitation, you may turn off the email notification by adding a line MAILTO=”” at the beginning of crontab. But when error occurs, you should remove this line temporarily and check the mails in /var/mail/root.
- check the crond log in /var/log/cron. This is what rsyslog produces for crond. You should make sure the cron.* is not commented in
/etc/rsyslog.confand rsyslog service is running. Unfortunately, the log in /var/log/cron is not very helpful. It just records when an entry in crontab is executed. It does not include the information that the commands in crontab are executed successfully or not. It even does not tell you whether the commands exist or not.
- log the output of the crontab command as:
11 2 * * * /path/to/your/command >> /tmp/mycommand.log 2>&1
Since the log above captures both stdout and stderr, you can know if crond failed to find your command(an stderr).