People come up with all sorts of debatable shell voodoo for debugging an errant cron job.

If the script runs successfully under your interactive shell, yet fails under cron, I am 99% sure for your case (and 100% sure for my case) that it is due to a difference in runtime environments.

For simple scripts, I’ve had the best luck with simply redirecting all script output to a file. Just add the following lines to the top of the script, set the cron job to run every minute, then inspect the log for failures.

# REDIRECT STDOUT AND STDERR TO LOG FILE
exec 1>/home/<username>/cron-debug.txt
exec 2>&1

For more involved scripts, it is typically faster to just resolve the env differences up-front instead of tackling each one bug-by-bug minute-by-minute.

1. Find your echo command

> whereis echo
echo: /bin/echo /usr/share/man/man1/echo.1.gz

2. Find your env command

> whereis env
env: /usr/bin/env /usr/share/man/man1/env.1.gz

3. Save your interactive runtime environment

> env > /home/<username>/env-runtime.txt

4. Use the paths you discovered with whereis to capture cron’s runtime environment

> crontab -e
*/2  *  *   *   *   /bin/echo `/usr/bin/env` > /home/<username>/env-cron.txt

5. Wait for env-cron.txt to appear

6. Compare the text files to see what the cron environment is missing

> cat /home/<username>/env-cron.txt
   HOME=/root
   LOGNAME=root
   PATH=/usr/bin:/bin
   LANG=en_US.UTF-8
   SHELL=/bin/sh

> cat /home/<username>/env-runtime.txt
   SHELL=/bin/bash
   TERM=xterm
   USER=root
   MAIL=/var/mail/root
   PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
   LANG=en_US.UTF-8
   SHLVL=1
   HOME=/root
   LOGNAME=root
   _=/usr/bin/env
   OLDPWD=/etc/cron.hourly

7. Supplement the failing script with any paths or variables that are missing from the cron environment

Other Common Mistakes

  • Using the wrong interpreter. (i.e. putting #!/bin/sh at the top of a script that uses bash-specific commands)
  • Putting spaces or lines in front of the interpreter line. (i.e. if you are having the shell resolve the script interpreter, it will fail if the #!/<path-to-interpreter> line does not start at row 1, column 1)
  • Running as the wrong user. (i.e putting a script that needs root permissions inside an unprivileged user’s crontab)

← Older   Newer →

Leave a Reply


<a href="" title="">, <abbr title="">, <acronym title="">, <b>, <blockquote cite="">, <cite>, <code>, <del datetime="">, <em>, <i>, <q cite="">, <s>, <strike>, <strong>