Setting environment variables in OS X
Posted
by
Percival Ulysses
on Super User
See other posts from Super User
or by Percival Ulysses
Published on 2012-09-18T21:00:26Z
Indexed on
2012/09/18
21:41 UTC
Read the original article
Hit count: 248
Despite the warning that questions that can be answered are preferred, this question is more a request for comments. I apologize for this, but I feel that it is valuable nonetheless.
The problem to set up environment variables such that they are available for GUI applications has been around since the dawn of Mac OS X. The solution with ~/.MacOSX/environment.plist never satisfied me because it was not reliable, and bash style globbing wasn't available. Another solution is the use of Login Hooks with a suitable shell script, but these are deprecated.
The Apple approved way for such functionality as provided by login hooks is the use of Launch Agents. I provided a launch agent that 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>
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 can see my local texmf 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.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.
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.
Finally, I would mention the sources I used as information on Launch Agents, but StackExchange doesn't let me [1], [2], [3]. Again, I am sorry that this is not a real question, I still hope it is useful.
© Super User or respective owner