Often, crontab
scripts are not executed on schedule or as expected. There are numerous reasons for that:
- wrong crontab notation
- permissions problem
- environment variables
This community wiki aims to aggregate the top reasons for crontab
scripts not being executed as expected. Write each reason in a separate answer.
Please include one reason per answer - details about why it's not executed - and fix(es) for that one reason.
Please write only cron-specific issues, e.g. commands that execute as expected from the shell but execute erroneously by cron.
Different environment
Cron passes a minimal set of environment variables to your jobs. To see the difference, add a dummy job like this:
Wait for
/tmp/env.output
to be created, then remove the job again. Now compare the contents of/tmp/env.output
with the output ofenv
run in your regular terminal.A common "gotcha" here is the
PATH
environment variable being different. Maybe your cron script uses the commandsomecommand
found in/opt/someApp/bin
, which you've added toPATH
in/etc/environment
? cron ignoresPATH
from that file, so runnningsomecommand
from your script will fail when run with cron, but work when run in a terminal. It's worth noting that variables from/etc/environment
will be passed on to cron jobs, just not the variables cron specifically sets itself, such asPATH
.To get around that, just set your own
PATH
variable at the top of the script. E.g.Some prefer to just use absolute paths to all the commands instead. I recommend against that. Consider what happens if you want to run your script on a different system, and on that system, the command is in
/opt/someAppv2.2/bin
instead. You'd have to go through the whole script replacing/opt/someApp/bin
with/opt/someAppv2.2/bin
instead of just doing a small edit on the first line of the script.You can also set the PATH variable in the crontab file, which will apply to all cron jobs. E.g.
My top gotcha: If you forget to add a newline at the end of the
crontab
file. In other words, the crontab file should end with an empty line.Below is the relevant section in the man pages for this issue (
man crontab
then skip to the end):Cron daemon is not running. I really screwed up with this some months ago.
Type:
If you see no number (i.e. cron's main PID), then cron is not running.
sudo /etc/init.d/cron start
can be used to start cron.EDIT: Rather than invoking init scripts through /etc/init.d, use the service utility, e.g.
EDIT: Also you could use systemctl in modern Linux, e.g.
The script filenames in
cron.d/
,cron.daily/
,cron.hourly/
, etc., should NOT contain dot (.
), otherwise run-parts will skip them.See run-parts(8):
So, if you have a cron script
backup.sh
,analyze-logs.pl
incron.daily/
directory, you'd best to remove the extension names.In many environments cron executes commands using
sh
, while many people assume it will usebash
.Suggestions to test or fix this for a failing command:
Try running the command in
sh
to see if it works:Wrap the command in a bash subshell to make sure it gets run in bash:
Tell cron to run all commands in bash by setting the shell at the top of your crontab:
If the command is a script, make sure the script contains a shebang:
I had some issues with the time zones. Cron was running with the fresh installation time zone. The solution was to restart cron:
Absolute path should be used for scripts:
For example,
/bin/grep
should be used instead ofgrep
:Instead of:
This is especially tricky, because the same command will work when executed from shell. The reason is that
cron
does not have the samePATH
environment variable as the user.If your crontab command has a
%
symbol in it, cron tries to interpret it. So if you were using any command with a%
in it (such as a format specification to the date command) you will need to escape it.That and other good gotchas here:
http://www.pantz.org/software/cron/croninfo.html
Cron is calling a script that is not executable.
By running
chmod +x /path/to/script
, the script becomes executable and this should resolve this issue.It is also possible that the user's password has expired. Even root's password can expire. You can
tail -f /var/log/cron.log
and you will see cron fail with password expired. You can set the password to never expire by doing this:passwd -x -1 <username>
In some systems (Debian, Ubuntu) logging for cron is not enabled by default. In /etc/rsyslog.conf or /etc/rsyslog.d/50-default.conf the line:
should be edited (
sudo nano /etc/rsyslog.conf
) uncommented to:After that, you need to restart rsyslog via
or
Source: Enable crontab logging in Debian Linux
In some systems (Ubuntu) separate logging file for cron is not enabled by default, but cron related logs are appearing in syslog file. One may use
to view cron-related messages.