Force launchd to re-read environment variables

Is there any way, short of rebooting, to force launchd to re-read environment variables newly defined in /etc/launchd.conf?

Can it be done with launchctl(1)?


Solution 1:

There is no way to do this, "launchd" is the master process, the equivalent of "init" in other unix systems, the only way in any other daemon would be to perform some sort of kill -HUP to reload config files etc, but this operation is not permitted on launchd. If you look it up in the process table it is the number 1 process, every other process that is currently running is in some way a child of it, so a reboot is the only way to achieve this. You may have further luck in setting those environment variables in another area that is more inclined to allow restarts.

    Dans-iMac:etc stuffe$ ps -ef | grep launchd | grep -v grep
    0     1     0   0  9:40am ??         0:09.47 /sbin/launchd
   65    18     1   0  9:40am ??         1:53.64 /usr/sbin/mDNSResponder -launchd
  213    73     1   0  9:41am ??         0:02.55 /System/Library/PrivateFrameworks/MobileDevice.framework/Versions/A/Resources/usbmuxd -launchd
    0    85     1   0  9:41am ??         0:00.08 /System/Library/CoreServices/ODSAgent.app/Contents/MacOS/ODSAgent -launchd
   89   230     1   0  9:41am ??         0:00.01 /sbin/launchd
  501   238     1   0  9:41am ??         0:00.23 /sbin/launchd
  501   933   238   0 10:53am ??         0:00.01 /System/Library/CoreServices/AirPort Base Station Agent.app/Contents/MacOS/AirPort Base Station Agent -launchd -allowquit

EDIT:

Of course, missing the obvious solution that you can add the relevant variables into the config file, and then just run the commands manually in order to escape the need for a reboot, nothing that only newly start programs will take account of any changes. I found this page which explains it in more detail:

Environment variables set in launchd will be available to all programs on the system. However since $HOME/.launchd.conf is not supported, this approach is used for global environment variables only.

The /etc/launchd.conf file contains a list of commands to be run by launchctl during startup. However environment variables set in /etc/launchd.conf cannot have spaces and cannot reference other environment variables; launchctl when run in Terminal does not suffer these limitations. Do note that /etc/launchd.conf does not exist by default, so we will need to create it.

A reboot is necessary to load the contents of /etc/launchd.conf. However if you were to run the corresponding launchctlcommands in Terminal, you can alleviate the need for the reboot. Just remember that if you only do the launchctl commands, and do not put the entries in /etc/launchd.conf, it will not persist after reboot.

If you want to have a system wide environment variable that uses spaces or be dependent upon another environment variable, you can put the launchctl commands into one of the files Terminal reads. You will have to quit and relaunch Terminal to access the newly set variables.

Solution 2:

Yes, you can use launchctl to add them for you.

for example from the terminal:

grep -E "^setenv" /etc/launchd.conf | xargs -t -L 1 launchctl

outputs on my machine:

 launchctl setenv _JAVA_OPTIONS -Djava.net.preferIPv4Stack=true
 launchctl setenv JMETER_HOME /Applications/apache-jmeter-2.10
 lauchctl setenv GRADLE_HOME /usr/local/gradle-2.0

Then you can restart whatever app that needs it form spotlight