After a bit of a struggle with mysterious PATH entries not working under Eclipse, I decided to do some research into how and when environment variables get set under OS/X.
Under X Windows (Unix, Xorg or X11) the system runs your .xinitrc (or variant) which sources (includes) your .profile file. So putting environment variables in there ensures they’re available to programs not started through a shell also.
Under OS/X, you’ll also be able to use .profile file, but it won’t get read on login. It will only be used by shells, and so any settings in there will only be available to programs started from a Terminal (or iTerm) window. The .bashrc and .bash_profile files suffer from essentially the same problem (but worse, as they’ll only work for programs started from a bash-shell or descendant of a bash-shell).
As it turns out, OS/X does offer a way to set environment variables on a per-user-at-login-basis, by placing them in a property-list file (.plist) in a hidden ‘.MacOSX’ folder in your homedir. .plist files are to OS/X what .ini files are to windows. But .plist files are XML-based and can therefore contain richer structures. They can be both in a binary format and a plain-text-xml (you can use the plutil tool included with OS/X to convert between the two). Manually editing the .plist while in xml format works fine, but you can also use the ‘defaults’ utility.
To read the entire file, in either binary or xml format:
defaults read ~/.MacOSX/environment
To read a single entry:
defaults read ~/.MacOSX/environment PATH
To set a single entry: (will convert the plist to binary)
defaults write ~/.MacOSX/environment PATH yadayada
These changes will only take effect at login, as this is when OS/X parses this file. You can also you the preference pane RCEnvironment for manual editing.
Things to consider:
This file is only read when login in on the machine through the login window. So these settings won’t be available when logging in remotely over ssh. (You could sorta remedy this by having your .profile parse and export defaults’ output when it sees you’re logging in remotely.)
No parameter expansion takes place, so using PATH PATH$:/bla will bork your file.
AFAIK, there is no way to run a shell-script in the login-process itself to dynamically establish environment variables.
It may be possible to start a shell-script using loginitems, LaunchAgents or a LoginHook which modifies the ‘master’ environment, but it may also be impossible to do this. I have yet to research this.
I encountered all this when doing perl-stuff from within Eclipse (which never involved a shell) and noticing it wasn’t finding perl modules that could be found from a Terminal. Turns out the PERL5LIB variable that I was setting in my .profile was not available from within Eclipse (or whatever it ran).
I’ll post a trivial ‘persist-environment’ shell-script which takes the current value of an environment variable and defaults-write’s it. I’ll also post a snippet that parses and exports the .plist for remote logins.