Thursday, July 19, 2007

why doesn't my shell script run under cron?

OK! Today's lesson is that using absolute paths to point to executables and the PATH statement in bash shell scripts are VERY important in allowing your shell script to run properly in cron!

Absolute Paths
For example, here is the start of a typical script that shuts down a service:
echo "Stopping web server.."

service httpd stop

Well, the bad part of this script is that is does not reference the full, absolute path to the service command. To fix this, make sure the full path is identified as in the sample code below:
echo "Stopping web server.."

/sbin/service httpd stop

PATH Statement
If you start a Cygwin bash script using an NT command script like so:
cd \scheduledTasks\500errors
bash -v "" 2>&1 log.txt

Your PATH statement may interfere with the running of your bash script. In my case, you can see I list c:\winnt\system32 first in my PATH. When the above script encountered a "sort" statement, the "sort" command that was used was the Windows sort command and NOT the Cygwin "sort". So, I got strange errors when I ran the script.

To reiterate, depending on the order of the directories in your PATH, sometimes a Windows executable will be chosen before the Cygwin executable. The "sort" and "head" commands are famous for doing this. So make sure the Cygwin bin directory is the first one listed in your PATH, like in the corrected version listed below:
cd \scheduledTasks\500errors
bash -v "" 2>&1 log.txt

When in doubt, do the following:
1) first, execute the bash script as your local user
2) if this works and you are starting the bash script from an NT script, execute the NT command or bat script to see if the script completes successfully
3) use Cygwin's own cron to kickoff the script. But that has issues of its own:

In cases where the Cygwin bash script is not working:
1) turn up debugging by using the -v switch to bash:
bash -v ""
2) write standard error and standard output to a file:
bash -v "" 2>&1 log.txt
3) compare environments
- run the command "env > myenv.log" from the shell where the program works and then execute "env > scriptenv.log" from the script. Then compare the two output files using diff:
diff myenv.log scriptenv.log

Other Good Troubleshooting Ideas
Here is some excellent advice from the Spike Source bloggers:

Hopefully, some of these suggestions may answer the exasperated cry, "Why doesn't my shell script run?!"


1 comment:

Ron said...

Thanks Tech Answer Guys, the trouble shooting tips helped out greatly

Feel free to drop me a line or ask me a question.