I use Paul Vixie’s cron daemon and I have learned environment always can stop your cron job from working probably, even you have tested in your normal terminal environment. A good lesson I have learned is they have different environments, and that’s why I have these environment variables set up in crontab:


PATH="/home/livibetter/bin:/usr/bin:/bin"
XDG_DATA_HOME=/home/livibetter/.local/share
PYTHONIOENCODING=utf8

As you can see a few environment variables must be set correctly in order to match normal terminal environments, or you may see errors like:


UnicodeEncodeError: 'ascii' codec can't encode character '\u2019' in position 82: ordinal not in range(128)
IOError: [Errno 2] No such file or directory: '/cron.gen/gh-trend.json'

Believe me those environment variables do not come easy when you can’t properly test the cron jobs, you can only guess what goes wrong and update the variables. The scripts run just perfectly normal, but I always know there sometimes are issues with cron environment, however, I never can find a way to tell cron daemon to run it just for testing. I checked manual pages, wiki pages, nothing about emulating the proper environments for testing.

So, the only way is to do it is on my own. From crontab(8):

Several environment variables are set up automatically by the cron(8) daemon. SHELL is set to /bin/sh, and LOGNAME and HOME are set from the /etc/passwd line of the crontab’s owner. HOME and SHELL may be overridden by settings in the crontab; LOGNAME may not.

(Another note: the LOGNAME variable is sometimes called USER on BSD systems… on these systems, USER will be set also.)

It looks like SHELL and HOME are all I need to set up, I don’t need LOGNAME. To set up the environment, using env to start an empty environment (-i) with those in crontab:


/usr/bin/env -i \
HOME=$HOME \
SHELL=/bin/sh \
PATH=/home/livibetter/bin:/usr/bin:/bin \
XDG_DATA_HOME=/home/livibetter/.local/share \
PYTHONIOENCODING=utf8 \
/bin/sh the_command_in_crontab

I can have the errors if I omit those important variables, I believe this is as close as I can get to test a cron job.