Binary Path / 9.8 / System PATH Variable

New Contributor

We have discovered a complication related to the move of the jamf binary in 9.8. We have several scripts that run as launch daemons, which in turn run jamf commands. These commands simply use 'jamf' instead of the full path, relying on the PATH variable to find the binary. The PATH variable in the launchd context doesn't appear to include /usr/local/bin. So, the scripts began failing with "command not found" errors.

We've identified two solutions. The first, is to update all of these custom scripts to use the hardcoded path (/usr/local/bin/jamf). The second, which brings some additional security concerns, is to modify the system environment variable to include the additional path. This can be accomplished with the following command:

sudo launchctl config system path '/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin' (requires a reboot)


Valued Contributor

I occasionally get "command not found" when using "sudo jamf manage recon" or "sudo jamf manage" with JSS 9.8

Contributor II

That's... a little less than optimal. Hopefully this will be addressed?

I was hoping to dodge the bullet with the whole binary relocation thing.

Valued Contributor

Would simply adding a file to /etc/paths.d/ to add the path to the directory where the jamf binary lives not work for you?

Why Jamf didn't put it in /usr/local/bin still makes my brain hurt. Like do you even computer bro?

Release Candidate Programs Tester


There are jamf and jamfAgent symlinks in /usr/local/bin, which allow the PATH environment variables available in Terminal to work without an issue. If you run which jamf or which jamfAgent in Terminal, the path to the symlink will appear instead of the actual location of the binary in question.

The problem appears to be that LaunchD items use different environment variables (ARD does as well, which was noted in another thread):

Where I've needed to have scripts figure out the current location of the jamf binary, I've added a function called CheckBinary to populate a variable named $jamf_binary, then called the CheckBinary function before running commands which reference $jamf_binary in place of /usr/sbin/jamf or /usr/local/bin/jamf.


CheckBinary (){

# Identify location of jamf binary.

jamf_binary=`/usr/bin/which jamf`

 if [[ "$jamf_binary" == "" ]] && [[ -e "/usr/sbin/jamf" ]] && [[ ! -e "/usr/local/bin/jamf" ]]; then
 elif [[ "$jamf_binary" == "" ]] && [[ ! -e "/usr/sbin/jamf" ]] && [[ -e "/usr/local/bin/jamf" ]]; then
 elif [[ "$jamf_binary" == "" ]] && [[ -e "/usr/sbin/jamf" ]] && [[ -e "/usr/local/bin/jamf" ]]; then

# Run the CheckBinary function to identify the location
# of the jamf binary for the jamf_binary variable.


$jamf_binary command_goes_here

Valued Contributor

so more scripting to work around issues in the tool that supposed to save you time and effort... don't get me wrong I love Casper but seriously y u do dis!

so launched doesn't respect paths in /etc/paths.d ? coz that's where munki puts itself and that seems to work....

Valued Contributor

Unfortunately Jamf was forced by Apple to change the lcoation of the binary as part of El Capitan's system integrity protection feature. Devs are no longer allowed to put binaries in /usr/sbin

New Contributor

We have also noticed differences in the PATH when deploying scripts and packages via Casper. When deploying packages, we've found the PATH to be '/bin:/sbin:/usr/bin:/usr/sbin:/usr/libexec' and when deploying scripts, '/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/jamf/bin' So, definitely not consistent behavior. The solution provided by rtrouton is probably going to be the safest approach, but will require touching/revisiting existing scripts and processes.

Valued Contributor


Unfortunately Jamf was forced by Apple to change the lcoation of the binary as part of El Capitan's system integrity protection feature. Devs are no longer allowed to put binaries in /usr/sbin

Dev's should never have been putting binaries in /usr/sbin or /usr/bin

/usr/local/bin and /usr/local/sbin is the correct place for 3rd party binaries.

Adding a file containing your path to /etc/paths.d should be enough to update the system env $PATH

This works for launchd jobs from my testing....

New Contributor III


sudo launchctl config system path '/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin'

Would you be able to explain why that command causes you security concerns?
Doesn't this just mean that LaunchDaemons are allowed to reference executables in that location without having to specify the full path within the scripts? A user would still need admin rights to create a LaunchDaemon able to reference executables in that location..?

@ooshnoo The /etc/paths.d suggestion sounds great, but doesn't seem to work at all for me.
launchd jobs still appear unable to access the path, even after a reboot.

Finally, does anyone know how to manually add paths to the ARD environment?
Creating a symlink in the below location works:
But obviously this is untenable in El Capitan due to /System also being blocked by the new security changes.

New Contributor


You are correct that it would take admin rights for this to be an issue, but the risk is still there. This link sums it up nicely:

You would also have to deal with the possibility that the PATH would be reset again by some patch or software update.

New Contributor III

@Coates Thanks for that, useful info.
I agree about not risking this breaking with an update, and furthermore it only seems to work irregularly :(
I'm still stuck with this, so I'm thinking of trying this method with my launch daemon:

Thanks again for your comments. I'll post back here if I find a reliable, secure, working solution.

New Contributor

Interesting that I found this post. I have a similar problem, although I'm new to scripting.

Here is my scenario - we have Kaspersky running on Macs managed via Landesk. Landesk does not care about Macs at all and we keep finding bugs that it takes them years to fix. One of the current bugs is that the Kav client does not pull definitions update automatically.

By running 'kav update' we can force agent to update. However when I script it and push it via Casper I get

Script exit code: 127
Script result: /Library/Application Support/JAMF/tmp/KavUpdate: line 2: kav: command not found

It looks like it is trying to use kav command from within the tmp folder and it doesn't know what it is. I navigated to the JAMF folder and ran 'kav update' there manually and it works. I would either need to specify where to look for the kav command or run this script from a different location.

Can anyone with scripting experience share some insight on how to achieve this?

Thank you.

Honored Contributor

Can you post the script?

New Contributor

It's just one line:

#!/bin/sh kav update -app=on