I often run into problems when I create a new script I want to start as a cron job and the scripts works fine when started manually but fails when running as a cron job. It’s usually because the environment it runs in is different i.e. different environment variables (e.g. PATH).
This is also probably happening so often because I run different OS: SLES, Debian and Mac OS X.
So I was looking for a way to test run my scripts i.e. run them in the same environment as if they had been running as cron jobs. First I was checking the time and quickly setting up a cron job with this script for the next minute. But this is just a stupid workaround. Every other time, I was too slow and had to do it twice or got fed up and set it for 2 minutes later just to see 2 minutes later that I had made a stupid mistake in the script… Moreover, when working directly working on a productive environment, making a mistake in the crontab could be fatal…
Actually the answer was really easy: The environment is defined in /etc/crontab:
# cat /etc/crontab # /etc/crontab: system-wide crontab # Unlike any other crontab you don't have to run the `crontab' # command to install the new version when you edit this file # and files in /etc/cron.d. These files also have username fields, # that none of the other crontabs do. SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin # m h dom mon dow user command 17 * * * * root cd / && run-parts --report /etc/cron.hourly 25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily ) 47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly ) 52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly ) #
So without the comments and the calls to run-parts:
# cat /etc/crontab | grep -v "#" | grep -v "^$" | grep -v /etc/cron SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
Of course you could also have other environment variables in there. So in order to run the script in the same environment as the cron job, you just need to run it in an empty environment setting the variables defined in /etc/crontab:
env - `cat /etc/crontab | grep -v "#" | grep -v "^$" | grep -v /etc/cron` your_script_name.sh
In case you want to be sure that you have the right environment you can also set up a cron job executing the following:
env > ~/cron.env
You can set it up for the next minute and once it’s been executed remove it. Then use the file cron.env on top of an empty environment:
env - `cat ~/cron.env` your_script_name.sh