Mac OS X Global Environment Variables

Having just spent way too long (couple hours) figuring out how to set environment variables on Mac OS X 10.5 in such a way that they were accessible from a bundled Java application (specifically, M2_HOME in IntelliJ so that the Maven integration would work 100%), I'm writing this up so that 1) I don't have to remember it later, and 2) to possibly save other folks the hassle.

For the impatient, the solution is

1) edit /etc/launchd.conf to contain a line like this:

setenv M2_HOME /opt/maven/2.0.9

2) reboot

Your environment variable will now be accessible in every possible context (that I could find) in which you can run your application. There are other ways to do this, but none of them worked for me. If you're interested in the details, read on.

The first thing I tried was creating a ~/.MacOSX/environment.plist as described in Apple's technical documentation. And to be honest, that *almost* works. Unfortunately it does not work for applications launched via Spotlight in 10.5 (which is how I launch pretty much everything, having gotten hooked on that way of launching things using Butler) - apps launched via Spotlight do not get the environment you define in the .plist. For me, this was a deal breaker, so I kept looking.

Also in Apple's technical documentation is a method for setting application-specific environment variables using the LSEnvironment key in the app's info.plist. This completely failed to do anything useful, perhaps because the app in question was a Java app.

I then went on to try to create a "prelude" script. Surprisingly, this didn't work either. In fact, it seemed the script never even got executed. I was able to change the CFBundleExecutable key to a completely nonsensical value and the app still launched. This method may actually work, I suspect there is some .plist caching going on in 10.5, and so you may need to reboot after making this change. I didn't, because frankly at that point my patience had run out.

By now, I had confirmed that my environment variable worked fine if I set it in .bash_profile and launched it from a shell. So clearly what I had was an issue with the parent process not being what I think it was (in the case of the environment.plist, the issue is that the environment.plist applies to the WindowServer, and Spotlight - aka "mds" in Activity Monitor - is not a child of WindowServer). This led me to wondering if there was a way to set environment variables in launchd, which is the parent of all processes (it is pid=1, equivalent to init on other *ix systems), which led me to this launchd article, from which I finally arrived at the solution posted above. Well, almost - per the man pages, I tried setting the variable in ~/.launchd.conf first, but best I can tell, that file never gets processed, so I set it in /etc/launchd.conf.

So there you have it. Setting an environment variable, which is so trivial in other OSes as to be taken for granted, can be painfully hard in Mac OS X.

Anybody know if this is

Anybody know if this is still the case for 10.6?
-r

thanks

thanks

Thanks for saving me the

Thanks for saving me the hassle!

Update for Snow

Update for Snow Leopard

Since MacOS X 10.6 Snow Leopard the limitation of environment.plist is gone. Even apps launched with spotlight will have access to the values defined in it.
As I see this post is referenced from many places and was very useful for me at the time, I thought it would be the right place to spread the word.

Any idea how to define one

Any idea how to define one environment variable in terms of another within /etc/launchd.conf?

I've found various resources

I've found various resources on how to set mac system wide environment variables. I've been successful with using launchd.conf to a degree. My issues arise when I want to specify spaces within the environment variable's value, e.g. JAVA_OPTS=-Xms512 -Xmx1024

If I put quotes around the value it doesn't work, if I use escapes '\', as for unix filenames, it doesn't work. All I get is an empty line when I try echo after a reboot. Any ideas?

Thank you!

Thank you!

thank you

thank you

Thanks for such post... You

Thanks for such post... You recommend

Thank you.

Thank you.

It's easier than you make it

It's easier than you make it out to be. You can edit ~/.launchd.conf and add the same setenv commands you described above. Using ~/launchd.conf is better because you don't have to use sudo, and you affect on your own user.

Also, you can run "grep ^setenv ~/.launchd.conf | launchctl" to update your environment variables without even logging out.

I wonder if there's a way

I wonder if there's a way the system can be told to set an environment variable for a specific application. If the app is designed to have its own environment variable or initialization file, this is not a problem at all. However, some apps may presume PATH is set a certain way. Setting PATH for all users or even an individual users's applications may be problematic if, for example, two different apps want different PATH variables. If one raps a shell script around the launch of the app, one can modify the PATH. Nonetheless this is sometimes difficult to do, and it would be nice if there were a way to tell the OS that a particular app should always be launched in an environment with such and such characteristics.

Thanks so much for posting

Thanks so much for posting this.

I had to create the file, and ... well ... haven't tried it yet, but have a similar problem, except with MAKEFLAGS (want -j3 always on).

* crosses fingers

=)

Absolutely right, I

Absolutely right, I struggled with this myself until I encountered your site. Thanks for that.
It is strange that the environment-variable-thing is so difficult to cope with.

"Thank you" hardly sums up

"Thank you" hardly sums up my gratitude. But it will have to do.

There should be 2 launchd

There should be 2 launchd instances; one is run as root and one is run as your login user (for your login session); I imagine the latter instance uses ~/.launchd.conf and is the right way to go; I'll test it out on my machine to get dbus working.

Thanks for writing this. I

Thanks for writing this. I too tried the LSEnvironment method with no success on a Java application. It's unfortunate that workarounds like this are necessary. I'd rather not set environment variables at the launchd level. Seems like that could cause problems for other users on the same computer. Hopefully, Apple will fix the LSEnvironment bug in an update.