0

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 2

2

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.

0

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:

  1. Use a full path specification for everything in your crontab

    For example : /usr/sbin/diskutil unmount volumeX

  2. Define (re-define) PATH in your crontab

    And as usual there are numerous ways to do this. If you want to use your "logged-in user" PATH as the PATH for 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 `crontab`  
    # you can re-activate the `printenv` cron job again to verify the new path
    

    A variation on this approach could be as follows:

    • Create a file named (for example) ~/.cronpath

    • Put 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 default PATH.

    • Source the file ~/.cronpath at reboot in your crontab:

    @reboot . /Users/$USER/.cronpath
    
    ...
    # remainder of crontab entries
    

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .