HowTo: Set an Environment Variable in Mac OS X - launchd.plist
launchd.plist is not a file, but rather a type of file. It is an XML document that holds parameters which can be loaded into launchd
. Here we’ll see how to use it to set environment variables.
Setting a Variable
For our first example, we’ll set the variable FOO
to the value of BAR
. Let’s look at an example and we’ll break it down:
/Library/ LaunchDaemons/ setenv.FOO.plist
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?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>setenv.FOO</string>
<key>ProgramArguments</key>
<array>
<string>/bin/launchctl</string>
<string>setenv</string>
<string>FOO</string>
<string>BAR</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>ServiceIPC</key>
<false/>
</dict>
</plist>
Breakdown
We will save in /Library/LaunchDaemons
as that is where system-wide daemons provided by the administrator are set up. Other options include:
/Library/LaunchAgents
- which is where per-user agents provided by the administrator are setup.~/Library/LaunchAgents
- which is where per-user agents provided by the user are setup.
We’ll name the file setenv.FOO.plist
, as the convention is to name the file Label.plist
and the label here is setenv.FOO
.
Label
The label can be anything, but needs to uniquely identify the job. We’ll use a convention of setenv.VARIABLE_NAME
.
ProgramArguments
Next is the program arguments of the daemon. launchctl
is used to set environment variables; it can be used in the terminal to set environment variables. This is what it would look like using the terminal:
Terminal - hostname:~ user$
1
/bin/launchctl setenv FOO BAR
Quit the terminal and reopen it
Terminal - hostname:~ user$
1
echo $FOO
Output
1
BAR
The issue however is if you reboot, you’ll lose the environment variable; fortunately we can put this command into ProgramArguments
. ProgramArguments
is just an array that lists the arguments for running the program.
RunAtLoad
This tells launchd
whether or not to run the job once it is read.
ServiceIPC
This was required in Mac OS X 10.4, but is inferred in Mac OS X 10.5 and later.
Creating the File
We can run the following command in the terminal to create the file.
Terminal - hostname:~ user$
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
cat << EOF | sudo tee /Library/LaunchDaemons/setenv.FOO.plist
<?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>setenv.FOO</string>
<key>ProgramArguments</key>
<array>
<string>/bin/launchctl</string>
<string>setenv</string>
<string>FOO</string>
<string>BAR</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>ServiceIPC</key>
<false/>
</dict>
</plist>
EOF
Load the file
And if we don’t want to log out and back in, we can just run this command in the terminal to set the variable.
Terminal - hostname:~ user$
1
launchctl load -w /Library/LaunchDaemons/setenv.FOO.plist
Setting Another Variable
When setting variables with /etc/launchd.conf
we couldn’t have spaces in the value, here we can. We’ll set the environment variable BAR
to the value TEST SPACES
:
/Library/ LaunchDaemons/ setenv.BAR.plist
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?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>setenv.BAR</string>
<key>ProgramArguments</key>
<array>
<string>/bin/launchctl</string>
<string>setenv</string>
<string>BAR</string>
<string>TEST SPACES</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>ServiceIPC</key>
<false/>
</dict>
</plist>
Create the File
Terminal - hostname:~ user$
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
cat << EOF | sudo tee /Library/LaunchDaemons/setenv.BAR.plist
<?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>setenv.BAR</string>
<key>ProgramArguments</key>
<array>
<string>/bin/launchctl</string>
<string>setenv</string>
<string>BAR</string>
<string>TEST SPACES</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>ServiceIPC</key>
<false/>
</dict>
</plist>
EOF
Load the File
Terminal - hostname:~ user$
1
launchctl load -w /Library/LaunchDaemons/setenv.BAR.plist
Issues
launchd
does not have ordering for loading services, so setting the environment variables will be run concurrently with any programs automatically opening on login. So can either close and reopen those apps that need the variables; login, then logout, then login again; or do not use “Reopen windows when logging back”.
References
- environment variables - Yosemite launchd.conf no longer works? - Stack Overflow
- launchd.plist(5) Mac OS X Manual Page
- [launchd-dev] About the ServiceIPC key
Parts of this series
- HowTo: Set an Environment Variable in Mac OS X
- HowTo: Set an Environment Variable in Mac OS X - Prerequisites
- HowTo: Set an Environment Variable in Mac OS X - Terminal Only
- HowTo: Set an Environment Variable in Mac OS X - $HOME/.MacOSX/environment.plist
- HowTo: Set an Environment Variable in Mac OS X - /etc/launchd.conf
- HowTo: Set an Environment Variable in Mac OS X - launchd.plist