PATH environment variables and Casper 9.8
In the wake of the release of Casper 9.8, where the Casper agent’s jamf and jamfAgent binaries have made their planned move from /usr/sbin to /usr/local/jamf/bin, a number of Casper-using folks who were used to running commands that referenced the jamf and jamfAgent binaries from Apple Remote Desktop (ARD) or other tools began to see errors that indicated that the jamf and jamfAgent binaries could not be found.
Conversely, opening a Terminal session and running the exact same command works fine.
Why are different tools acting differently? The root cause is that they each have different PATH environmental variables, usually referred to as $PATH. For more details, see below the jump.
PATH environmental variables define which directories in the OS are searched for commands. When a command name is specified, the OS searches through the directories defined in the PATH environmental variables, examining each directory and looking for an program which matches the command name. Once the OS finds it, that command is executed.
However, if a command is not found as a result of this search, an error results instead of the command being executed.
By default, a Terminal session in OS X will have the following PATH environmental variables:
The jamf and jamfAgent binaries are located in /usr/local/jamf/bin, but JAMF also added symlinks to /usr/local/bin for both of these binaries. Because /usr/local/bin is included in the OS’s search, /usr/local/bin/jamf and /usr/local/bin/jamfAgent can be run in Terminal using just the commands jamf and jamfAgent.
In contrast, Apple Remote Desktop has different PATH environmental variables:
As /usr/local/bin is not referenced in ARD’s $PATH, the OS does not know to search that directory. As a consequence, /usr/local/bin/jamf and /usr/local/bin/jamfAgent are not located and an error results.
A similar situation applies to LaunchD items, like LaunchAgents and LaunchDaemons. LaunchD items have the following PATH environmental variables:
As with ARD, /usr/local/bin is not referenced in LaunchD items’ $PATH and the OS does not know to search that directory.
A commonality between all three (Terminal, ARD and LaunchD) is that they all include /usr/sbin as part of their $PATH, so the /usr/sbin/jamf and /usr/sbin/jamfAgent binaries are always found when Terminal, ARD and LaunchD items search for those commands.
This condition does not apply to /usr/local/bin, as only Terminal sessions include /usr/local/bin as part of $PATH.
Now that the root cause of the issue has been identified, what can be done about it? A common solution is to refer to the complete directory path to the command, starting from the root level. In the case of the jamf binary, one way to address this is to use /usr/local/bin/jamf in scripts and commands. That way, the OS doesn’t have to search for the command; it’s being told exactly where the command is.
However, a complication in the case of the Casper agent is that the location of the jamf and jamfAgent binaries depends on the operating system version, as JAMF made the decision to move the binaries only if the Mac in question is running 10.7.x or later.
The script above contains a function called CheckBinary, which populates a variable named $jamf_binary. The script calls the CheckBinary function before running commands which reference $jamf_binary, in place having to hardcode /usr/sbin/jamf or /usr/local/bin/jamf in the script.
The CheckBinary function can also be added to scripts which are being triggered by LaunchD items, allowing the jamf binary to be located correctly by the OS before running commands using the jamf binary.