I recently had to re-install 10.9.5 (default install) and am now finding that bash scripts that run perfectly from the command line (~/Me...) no longer work using crontab. I use crontab to invoke "Diskutil unmount volumeX" but am getting mail from cron saying "diskutil" command not found. Is it a PATH issue and if so how would I fix it. Thank you in advance for any help.
2 Answers
cron uses /usr/bin:/bin as the default PATH and diskutil is in /usr/sbin.
Specify the full path to diskutil or add a line like PATH=/usr/bin:/bin:/usr/sbin:/sbin to the start of your crontab.
Enter which diskutil to find its path, or enter echo $PATH to find the path where your commands are working.
Question:
Is it a PATH issue and if so how would I fix it.
Answer to "Is this a PATH issue?":
It most probably is a "PATH issue". But the real issue is not knowing the true value of $PATH that cron uses. That is the issue this answer will address.
As a user of cron, one of the things you should understand is that although cron executes your crontab instructions on your behalf, and under your userid, it does this within a different environment than you do as a "logged in" user.
Perhaps the easiest way to discover what your environment is when running a job from cron is to ask cron to tell you! That's easily done as follows:
% crontab -e
in your editor, add the following line, then save & close your new crontab
- printenv > /Users/$USER/mycronenvironment.txt 2>&1
now wait for the output:
% tail -f ~/mycronenvironment.txt
You'll want to stop this shortly, so edit and save your crontab. Your output will resemble this:
SHELL=/bin/sh
USER=seamus
PATH=/usr/bin:/bin
PWD=/Users/seamus
SHLVL=1
HOME=/Users/seamus
LOGNAME=seamus
_=/usr/bin/printenv
Note the PATH variable is limited to /usr/bin & bin. So - your cron job will look nowhere else for a file. You may now wish to compare this environment against the one in your interactive login shell. Simply run printenv from your login shell (zsh on later model Macs):
% printenv
...
PATH=/opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Applications/VMware Fusion.app/Contents/Public:/Library/Apple/usr/bin
...
This difference in the PATH environment variables explains the source of an "unknown command" error generated by cron: the command is not on the PATH of the shell used by cron.
Answer to "How do I fix this?":
In general, there are two methods:
Use a full path specification for everything in your
crontabFor example :
/usr/sbin/diskutil unmount volumeXDefine (re-define)
PATHin yourcrontabAnd as usual there are numerous ways to do this. If you want to use your "logged-in user"
PATHas thePATHfor your "cron user":% echo $PATH /opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Applications/VMware Fusion.app/Contents/Public:/Library/Apple/usr/bin% crontab -e
copy and paste the $PATH string at the top of the file as follows:
PATH=/opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Applications/VMware Fusion.app/Contents/Public:/Library/Apple/usr/bin
save & close your
crontabyou can re-activate the
printenvcron job again to verify the new pathA variation on this approach could be as follows:
Create a file named (for example)
~/.cronpathPut a single line in this file:
PATH=/usr/bin:/bin:<other folders>where <other folders> is a colon-separated list of dirs you wish to add to the defaultPATH.Source the file
~/.cronpathat reboot in yourcrontab:
@reboot . /Users/$USER/.cronpath...
remainder of crontab entries
- 4,547