# Setting EnvironmentVariables on MacOS
While general linux instructions described in [[Setting Environment Variables on Linux]] will work for command line applications, for GUI applications `launchctl` needs to be called, for every environment variable and at each startup. The solution involves a launch agent, triggered at each login.
These steps are slightly modified to use `zsh` and `.zprofile`. The original solution is described [here](https://stackoverflow.com/a/32405815) and [here](https://github.com/ersiner/osx-env-sync).
1. Create `$HOME/Library/LaunchAgents/osx-env-sync.plist` with the following contents:
```xml
<?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>osx-env-sync</string>
<key>ProgramArguments</key>
<array>
<string>zsh</string>
<string>-l</string>
<string>-c</string>
<string>
$HOME/.osx-env-sync.sh
</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
```
2. Create `$HOME/.osx-env-sync.sh` with the following contents
```sh
grep "^export" $HOME/.zprofile | while IFS=' =' read ignoreexport envvar ignorevalue; do
launchctl setenv ${envvar} ${!envvar}
done
```
3. Make the script executable `chmod +x ~/.osx-env-sync.sh`
4. Call `launchctl load ~/Library/LaunchAgents/osx-env-sync.plist`
The script will parse `.zprofile`, extract all `EXPORT` statements and call `launchctl setenv` for each. The launch agent is used to ensure the script is executed at login.
If you need to force environment variable reload you need to call
```sh
launchctl unload ~/Library/LaunchAgents/osx-env-sync.plist
launchctl load ~/Library/LaunchAgents/osx-env-sync.plist
```