I wanted to automate a certain task on a CentOS server, so I wrote a bash script to perform this task, with the intention of using cron to provide the scheduling.
The script worked beautifully when invoked from the SSH bash shell. However, when cron calls the script, the task failed.
Looking at the error logs, it seems like some line of commands failed with “command not found” error. This usually means that the program called in those lines are nowhere to be found in the current $PATH environment variable.
I have always assumed that when a cron job executes, it inherits the same environment variables as when you log in directly to the shell via SSH. The above error proves that this is not the case.
Finding the difference
In order to modify the script so that it will work with cron, I needed to know what the environment looks like when cron calls a script. Thankfully, a quick Google search revealed this post on stackoverflow.
First, we add the following line to the crontab. This will save the output of the env command, which is the list of all current environment variables, into a file once every minute. We just need it to run once, therefore remove the line from crontab once the first minute mark has passed.
* * * * * env > ~/env.out
The contents of this output file reveal that the environment variables loaded when cron runs a script is a very small subset of the environment variables loaded when you get to the shell prompt via SSH login.
Load the environment and test
Now we can use this output file to load the same environment variables as when cron executes a script, and modify the script we wish to run via cron until it works.
# env - `cat ~/env.out` /bin/sh # ./script.sh