Why crontab scripts are not working?

Different environment

Cron passes a minimal set of environment variables to your jobs. To see the difference, add a dummy job like this:

* * * * * env > /tmp/env.output

Wait for /tmp/env.output to be created, then remove the job again. Now compare the contents of /tmp/env.output with the output of env run in your regular terminal.

A common "gotcha" here is the PATH environment variable being different. Maybe your cron script uses the command somecommand found in /opt/someApp/bin, which you've added to PATH in /etc/environment? cron ignores PATH from that file, so runnning somecommand 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 as PATH.

To get around that, just set your own PATH variable at the top of the script. E.g.

#!/bin/bash
PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# rest of script follows

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.

PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

15 1 * * * backupscript --incremental /home /root

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):

   Although cron requires that each entry in a crontab end  in  a  newline
   character,  neither the crontab command nor the cron daemon will detect
   this error. Instead, the crontab will appear to load normally. However,
   the  command  will  never  run.  The best choice is to ensure that your
   crontab has a blank line at the end.

   4th Berkeley Distribution      29 December 1993               CRONTAB(1)

Cron daemon is not running. I really screwed up with this some months ago.

Type:

pgrep cron 

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.

sudo service cron start

EDIT: Also you could use systemctl in modern Linux, e.g.

sudo systemctl start cron

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):

   If neither the --lsbsysinit option nor the --regex option is given then
   the names must consist entirely of upper and lower case  letters,  dig‐
   its, underscores, and 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_-]+$).

So, if you have a cron script backup.sh, analyze-logs.pl in cron.daily/ directory, you'd best to remove the extension names.