In one of our last articles, we talked about the cron job scheduler on Linux servers. Today, we'll switch gears from a simple tutorial to try to go more in depth about the kind of problems administrators tend to run into with cron. Debugging cron happens more often than most of us would like, and a lot of our time is spent just looking for what's wrong rather than actually fixing. Most of the mistakes are common, though, and I’ll try to go through a few of them along with debugging methods in this article.
1. Wrong command syntax in the ‘crontab’ file
2. Wrong path to your script file
3. No execute permissions on your script file
4. Using undeclared variables in your profile
I’ll go through all these issues below. I have run into all of them myself, and more often that I like to admit, so I should serve as a good learning tool.
First thing you need to do, if your cron job didn’t run as expected, is look to the /var/log/cron file. You can find the records of all cron jobs your server has run:
Jun 24 12:42:01 serversuit CROND: (root) CMD (echo "hello" > /tmp/testfile) Jun 24 12:43:01 serversuit CROND: (root) CMD (echo "hello" > /tmp/testfile)
I have the test cronjob running ‘echo “hello”’ and writing the output to the ‘/tmp/testfile’ file, as you can see. You can see that this command was launched at the time specified. If you didn’t find the log entry for your job, then you need to check time settings in the ‘crontab’ file. If you just forgot to provide some data, crontab will return an error that might look like this:
crontab: installing new crontab "/tmp/crontab.lTX0SZ":1: bad day-of-week errors in crontab file, can't install. Do you want to retry the same edit?
You also need to remember that cron is using 24-hour time format and therefore your config should take that into account:
# Your script will run at 7:00am instead of 7:00pm 0 7 * * * /scripts/testscript.sh # Now your script will run at 7:00pm as expected! 0 19 * * * /scripts/testscript.sh
The other common error is forgetting to include the complete path to the script:
# Your script will not run because cron daemon can’t find the file 0 19 * * * testscript.sh # Now you provide the full path and it will launch 0 19 * * * /scripts/testscript.sh
Always remember that your script file should have execute permissions. This issue isn't as common, because you'd usually check that your script is working which obviously requires executing it. Read both of our articles on file permissions for more details on this topic. However, if you created a cron job that will run from another user account, this might be a problem:
[root@serversuit ~]# crontab -u apache -e
You need to make sure that the ‘apache’ user can read and execute your script!
Finally, the last problem on today's menu, and possibly the least obvious, is using custom environment variables in your profile. If you take a look at your ‘.bash_profile’ file you can find some custom PATH variables which are being declared during the login:
# User specific environment and startup programs PATH=$PATH:$HOME/bin:/usr/sbin:/usr/bin:/script export PATH
The problem is that your script will not have that PATH variable available when run by cron, so you can either provide full paths for all system calls as I suggested above, or include bash profile in your script. Here is my ‘testscript.sh’ file as an example:
#!/bin/bash source $HOME/.bash_profile
Now your script should have access to all your environment variables. Note that if you run that script from another user, it will use that user profile - not yours!
You also can add environment variables to the script directly:
#!/bin/bash export JAVA_HOME=/path/to/jdk
Your script will have the standard $JAVA_HOME variable declared. Configure the crontab job to set variables that the scripts can use during runtime.
Finally, you can declare a global variable in the crontab file:
JAVA_HOME=/path/to/jdk * * * * * /scripts/testscript.sh
What if you still have problems with your script? It can happened to the best of us. If you've gone through these common problems and still having issues, unfortunately it's time to go back to the drawing board and start debugging.
Every cron job can be set to send an email with the results. You should note, though, that if there is no output, there will be no email. Your user also needs to have a valid email address in the account settings, or you can set the “MAILTO” environment variable to send mail to a custom mailbox:
MAILTOemail@example.com 0 19 * * * /scripts/testscript.sh
You also can log the output of your script in a local file:
0 19 * * * /scripts/testscript.sh &> /logs/testscript.log
I think that should cover the most common cron jobs problems but, of course, you can run into some unique problems of your own.
ServerSuit offers automatic cron job management *nudge nudge wink wink* so check out our linux server management suite. Always 30 days free when you first sign up and register a server! Don't forget to like us on Facebook and follow @serversuit for our latest updates and articles!
Until the next one!