Solution for both command line and GUI applications from a single source (works with Mac OS X v10.10 (Yosemite) and Mac OS X v10.11 (El Capitan))
Let's assume you have environment variable definitions in your ~/.bash_profile
like in the following snippet:
export JAVA_HOME="$(/usr/libexec/java_home -v 1.8)"
export GOPATH="$HOME/go"
export PATH="$PATH:/usr/local/opt/go/libexec/bin:$GOPATH/bin"
export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"
export MANPATH="/usr/local/opt/coreutils/libexec/gnuman:$MANPATH"
We need a Launch Agent which will run on each login and anytime on demand which is going to load these variables to the user session. We'll also need a shell script to parse these definitions and build necessary commands to be executed by the agent.
Create a file with plist
suffix (e.g. named osx-env-sync.plist
) in ~/Library/LaunchAgents/
directory with the following contents:
<?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>osx-env-sync</string>
<key>ProgramArguments</key>
<array>
<string>bash</string>
<string>-l</string>
<string>-c</string>
<string>
$HOME/.osx-env-sync.sh
</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
-l
parameter is critical here; it's necessary for executing the shell script with a login shell so that ~/.bash_profile
is sourced in the first place before this script is executed.
Now, the shell script. Create it at ~/.osx-env-sync.sh
with the following contents:
grep export $HOME/.bash_profile | while IFS=' =' read ignoreexport envvar ignorevalue; do
launchctl setenv "${envvar}" "${!envvar}"
done
Make sure the shell script is executable:
chmod +x ~/.osx-env-sync.sh
Now, load the launch agent for current session:
launchctl load ~/Library/LaunchAgents/osx-env-sync.plist
(Re)Launch a GUI application and verify that it can read the environment variables.
The setup is persistent. It will survive restarts and relogins.
After the initial setup (that you just did), if you want to reflect any changes in your ~/.bash_profile
to your whole environment again, rerunning the launchctl load ...
command won't perform what you want; instead you'll get a warning like the following:
<$HOME>/Library/LaunchAgents/osx-env-sync.plist: Operation already in progress
In order to reload your environment variables without going through the logout/login process do the following:
launchctl unload ~/Library/LaunchAgents/osx-env-sync.plist
launchctl load ~/Library/LaunchAgents/osx-env-sync.plist
Finally make sure that you relaunch your already running applications (including Terminal.app) to make them aware of the changes.
I've also pushed the code and explanations here to a GitHub project: osx-env-sync.
I hope this is going to be the ultimate solution, at least for the latest versions of OS X (Yosemite & El Capitan).
env "switch.1.disabled=true" open -n /Applications/Eclipse.app/
to launch GUI application with a new set system environment. – Hong