After many trials with different options I conclude:
Is there a unified way to set the PATH
for applications launched by different means (like shell script, Finder and Spotlight)? Well, yes and no:
- No: Setting
PATH
in shell start up scripts (e.g. .bashrc
) works only for apps launched by shells.
- No: Setting
PATH
for the current launchd
process via launchctl setenv PATH <...>
does not work for me at all.
- Yes: Setting
PATH
in /etc/launchd.conf
(and restarting the system) will make the appropriate PATH
visible in applications launched by Spotlight, Dock and Finder and subsequently (local) shells.
- No: Remotely invoked shells do not inherit the environment. (See ...why do remote shells via ssh do NOT inherit the environment..)
Notes for set-up of shells:
For correct functioning in local shells it is important to switch off the use of /usr/libexec/path_helper
, because the default paths in /etc/paths
might change the order of the paths in PATH
.**
To accommodate remote shells you need to re-import the launchd
environment into the shell. Use something like this in your .bashrc
:
# the vexatious path stuff
eval $(launchctl export)
Unfortunate consequences of the whole issue are:
- No way to have these unified settings on a per user basis. (
~/.launchd.conf
does not work.)
- No easy way to construct the PATH from different sources using techniques like home directory expansion et al.
Yosemite
/etc/launchd.conf
is no longer supported in 10.10. See man launchctl
:
The /etc/launchd.conf file is no longer consulted for subcommands to run during early boot time; this functionality was removed for security considerations.
You can now for example save this plist as ~/Library/LaunchAgents/my.startup.plist
:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>my.startup</string>
<key>ProgramArguments</key>
<array>
<string>sh</string>
<string>-c</string>
<string>launchctl setenv PATH /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
The launchctl setenv
command is ran as the user, so it only applies to processes launched in the user domain.
This method doesn't apply to applications that are reopened at login if "Reopen windows when logging back in" is checked.
Mavericks and earlier
In 10.9 and earlier, you can for example run
echo setenv PATH /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin|sudo tee -a /etc/launchd.conf
and then restart to apply the changes.
Other methods
/etc/paths
and /etc/paths.d/
apply only (or mainly) to shells. The lines in /etc/paths
and /etc/paths.d/*
are added to the path by path_helper, which is run from /etc/profile
, /etc/zshenv
, and /etc/csh.login
. I don't know any programs other than shells that would consider /etc/paths
or /etc/paths.d/
.
~/.MacOSX/environment.plist
stopped working in 10.8.
Best Answer
Solution
The solution uses two files:
environment.plist
andenvironment.conf
.environment.plist
should be placed in~/Library/LaunchAgents
for a per user solution (recommended), or in/Library/LaunchAgents
for a global solution (not recommended – potential security loophole).environment.conf
can be placed almost anywhere.$PATH_TO_ENVIRONMENT_CONF
can be relative, but only to the 'default' environment variables, or any that are defined in aEnvironmentVariables
key. 1environment.plist
:environment.conf
:How it works
When a user logs in, the LaunchAgents in
~/Library/LaunchAgents
are executed. In this case,sh -c xargs -L 1 launchctl < $PATH_TO_ENVIRONMENT_CONF
is executed.launchctl
manages daemons and agents. In this case, we are using it to set an environment variable accessible to all applications and the shell.This solution can also be extended to other launchctl subcommands.