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.

nohillside
  • 100,768

2 Answers2

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.

larsw
  • 53
Lri
  • 105,117
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

Seamus
  • 4,547