18
13
How does one set up environment variables in Mac OS X such that they are available for GUI applications without using ~/.MacOSX/environment.plist or Login Hooks (since these are deprecated)?
18
13
How does one set up environment variables in Mac OS X such that they are available for GUI applications without using ~/.MacOSX/environment.plist or Login Hooks (since these are deprecated)?
8
The solution uses the functionality of launchctl
, combined with a Launch Agent to mimic the login hooks of old. For other solutions using the store of launchd
, see this comparison.
The launch agent used here is located in /Library/LaunchAgents/:
<?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>user.conf.launchd</string>
<key>Program</key>
<string>/Users/Shared/conflaunchd.sh</string>
<key>ProgramArguments</key>
<array>
<string>~/.conf.launchd</string>
</array>
<key>EnableGlobbing</key>
<true/>
<key>RunAtLoad</key>
<true/>
<key>LimitLoadToSessionType</key>
<array>
<string>Aqua</string>
<string>StandardIO</string>
</array>
</dict>
</plist>
One important thing is the RunAtLoad key so that the launch agent is executed at the earliest time possible.
The real work is done in the shell script /Users/Shared/conflaunchd.sh, which reads ~/.conf.launchd and feeds it to launchctl
:
#! /bin/bash
#filename="$1"
filename="$HOME/.conf.launchd"
if [ ! -r "$filename" ]; then
exit
fi
eval $(/usr/libexec/path_helper -s)
while read line; do
# skip lines that only contain whitespace or a comment
if [ ! -n "$line" -o `expr "$line" : '#'` -gt 0 ]; then continue; fi
eval launchctl $line
done <"$filename"
exit 0
Notice the call of path_helper
to get PATH set up right. Finally, ~/.conf.launchd looks like that
setenv PATH ~/Applications:"${PATH}"
setenv TEXINPUTS .:~/Documents/texmf//:
setenv BIBINPUTS .:~/Documents/texmf/bibtex//:
setenv BSTINPUTS .:~/Documents/texmf/bibtex//:
# Locale
setenv LANG en_US.UTF-8
These are launchctl
commands, see its manpage for further information. Works fine for me (I should mention that I'm still a Snow Leopard guy), GUI applications such as texstudio and TeXShop can see my own tex tree. Things that can be improved:
The shell script has a #filename="$1"
in it. This is not accidental, as the file name should be feeded to the script by the launch agent as an argument, but that doesn't work.
As mentioned here (German and behind a paywall!), it is possible to put the script in the launch agent itsself.
I am not sure how secure this solution is, as it uses eval
with user provided strings.
I think to remember that the definition of MANPATH using this method didn't work well, but I'm not sure.
It should be mentioned that Apple intended a somewhat similar approach by putting stuff in ∼/launchd.conf, but it is currently unsupported as to this date and OS (see the manpage of launchd.conf
). I guess that things like globbing would not work as they do in this proposal. And of course one can put these files anywhere else, except the launch agent which must reside in /Library/LaunchAgents/ or ~/Library/LaunchAgents/.
Finally, I should mention the sources I used as information on Launch Agents: 1, 2, 3, 4.
Update: This does not work in version 10.8 at the moment. Workarounds on a per application basis are described here and here.
By the way, if one wants to define the PATH-Variable in a Terminal environment and uses this launch agent, I suggest to write export PATH=.:"$(launchctl getenv PATH)"
in ~/.bash_profile (similarly for other shells). This is possible since path_helper
is called in the shell script. For more details on the PATH variable in OS X, check this answer.
16
On Mountain Lion all the /etc/paths
and /etc/launchd.conf
editing doesn't take any effect!
Apple's Developer Forums say:
"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."
So I directly edited the app's Info.plist
(right click on "AppName.app" (in this case SourceTree) and then "Show package contents
")
and added a new key/dict pair called:
<key>LSEnvironment</key>
<dict>
<key>PATH</key>
<string>/Users/flori/.rvm/gems/ruby-1.9.3-p362/bin:/Users/flori/.rvm/gems/ruby-1.9.3-p362@global/bin:/Users/flori/.rvm/rubies/ruby-1.9.3-p326/bin:/Users/flori/.rvm/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:</string>
</dict>
(see: LaunchServicesKeys Documentation at Apple)
now the App (in my case SourceTree) uses the given path and works with git 1.9.3 :-)
PS: Of course you have to adjust the Path entry to your specific path needs.
1
Thank you! This was perfect for me. On 10.11 (El Capitan) I did have to also run the commands provided by Matthew in order to see my changes to Info.plist
take effect.
3
The answer provided by @flori works for me on Maverick provided I run the following commands in Terminal after changing the plist file
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -kill -r -domain local -domain system -domain user
killall Finder
I had the same behavior with El Capitan, and I have added your point to @flori's answer – Seki – 2016-08-30T17:35:18.910
2
The answer provided by @percival-ulysses works for me on 10.9 Mavericks with the following small change: edit /Users/Shared/conflaunchd.sh script right before exit 0
and add the lines
killall Dock
killall SystemUIServer
to restart the Dock and the menubar. After this the applications started from the Dock or from Spotlight will inherit the correct PATH. If you use Finder to start the PATH-critical applications, then killall Finder
may be added too.
In the .bash_profile
I use the line
export PATH=`launchctl getenv PATH`
to set the PATH for the Terminal, this way the PATH is controlled from the same location, the ~/.conf.launchd file.
0
Another option is to use /etc/launchd.conf
. For example I have changed the default PATH
by adding this line to /etc/launchd.conf
:
setenv PATH ~/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/libexec:/usr/texbin
You can apply changes to /etc/launchd.conf
by either restarting, or by running launchctl < /etc/launchd.conf; sudo launchctl < /etc/launchd.conf
and terminating and relaunching processes.
Settings in /etc/launchd.conf
apply to both the root launchd process and per-user launchd processes. Environment variables set with setenv
in /etc/launchd.conf
are shown by both sudo launchctl export
and launchctl export
.
@ersin-er The answer from StackOverflow "Solution for both command line and GUI apps from a single source (works with Yosemite & El Capitan)" may be of interest to people finding this question.
– l --marc l – 2016-01-07T07:15:41.197