I asked this question on the Apple Developer Forums as well and got back this, official response.
Change the Info.plist of the .app itself to contain an "LSEnvironment"
dictionary with the environment variables you want.
~/.MacOSX/environment.plist is no longer supported.
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
The correct file, prior to Mavericks, was
~/.MacOSX/environment.plist
. This is no longer supported.In Darwin, and therefore in Mac OS X, the proper place to set these is in
/etc/launchd.conf
to apply to all processes; if relating to user shells specifically, use the appropriate shell files instead, depending on the shell in question. See thelaunchd.conf
andlaunchctl
man pages for more.That said...
If you're goal is specifically to see these applied for ssh sessions then you need to be aware that ssh, for security reasons, doesn't apply environment variables in this manner. In fact a ssh session normally receives a much more restrictive set of environment variables from the OS as it's not what is known as a "login" or "interactive" shell, it's classified as an "non-interactive" shell. (See
man bash
for more on shell types.) The way ssh handles environment variables is well covered in the ssh/sshd docs and man pages.For ssh -- which is it's own shell, akin to bash -- environment variables for the session are stored in
~/.ssh/environment
as the per-user equivalent of setting these for bash or csh, etc in their relevant launch files. This is probably where you want to set your ENV variables for your user ssh sessions, though you don't detail why you're looking to assign ENVs globally in your original post, which would have been helpful in providing a solution. I'd suggest you set them explicitly on a user per user basis to maintain proper security based on each respective account following the least restrictive privilege/attribute best practice.If for some reason you wish to ignore he security implications of this, then set
PermitUserEnvironment
in your ssh configs. Note that this is disabled ifUseLogin
is enabled. IMPORTANT: Realize that this means that user accounts set to use/bin/false
as their shell - the typical method for disabling a user account - can now potentially get around this restriction and could now become active, which is dangerous. Many accounts are set to use/bin/false
as their shell as a security expectation.Bottom line is you shouldn't be doing this globally and expecting ssh to propagate ENV for security reasons. Your question is, effectively, purposely asking how to defeat several mechanisms that exist for security reasons.