Macでの環境変数（environment variables）の設定方法

# 対象
システムレベルでグローバルに有効にしたい環境変数の話。GUIアプリケーション上で有効にしたい、などが対象ユースケース。
ターミナルコンソール上で有効になる `.bashrc` や `.bash_profile` に `export A=hogehoge` の話はここでは割愛。
下記のように、**Mac OS のバージョンによって設定方法が違うので注意。** Mac OS 10.10 (Yosemite) 以降は一つ目の同じ方法で問題ない。

* Mac OS 10.10 (Yosemite) 以降
  * Mac OS 10.11 (El Capitan), macOS 10.12 (Sierra), macOS 10.13 (High Sierra)
* Mac OS 10.8 (Mountain Lion), 10.9 (Mavericks)
* Mac OS 10.7 (Lion) 以前

## ユースケース Use Case
* `JAVA_HOME` 設定したい。`M2_HOME` 設定したい。
* Android Studio で、`ANDROID_HOME` や `ANDROID_SDK_ROOT` を設定したい。
* `API_KEY`, `CLIENT_ID`, `CLIENT_SECRET` といった類のハードコードしたくない値を設定したい。
* etc, etc

# Mac OS 10.10 (Yosemite) 以降
* `launchctl` を使う
* 10.8 (Mountain Lion), 10.9 (Mavericks)で有効だった、 `/etc/launchd.conf` は、10.10 (Yosemite) 以降では **使えない。**

## 設定手順 Procedure
基本的には2ステップ。
1. plist ファイルを作る。
2. そのファイルを、`launchctl load` する。

- 1. plist ファイルを作る。
    - ファイルのパスは、主に以下2通り。
        - `/Library/LaunchAgents/*****.plist` : システム全体で有効になる。
        - `~/Library/LaunchAgents/*****.plist` : ログインユーザのみで有効になる。
    - ファイル名は任意だが、 `*****.plist` とかにして、***** にはLabelの値を設定しておくと管理しやすい。
        - 下記は Label=setenv.M2_HOME としたときの、setenv.M2_HOME.plist のサンプル。
    - RunAtLoad=true で起動時に load される。

```
<?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.M2_HOME</string>
  <key>ProgramArguments</key>
  <array>
    <string>/bin/launchctl</string>
    <string>setenv</string>
    <string>M2_HOME</string>
    <string>/usr/local/Cellar/maven31/3.1.1/libexec</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
  <key>ServiceIPC</key>
  <false/>
</dict>
</plist>
```

- 2. そのファイルを、`launchctl load` する。

これはすぐにその環境変数 plist を有効にしたいときに。再起動や再ログインせずに有効になるので便利。

```
launchctl load ~/Library/LaunchAgents/setenv.M2_HOME.plist 
```

値を修正したい場合にもう一度 `launchctl load` しても、下記のようにエラーになってしまうので、

```
launchctl load ~/Library/LaunchAgents/setenv.M2_HOME.plist 
/Library/LaunchAgents/setenv.M2_HOME.plist: Operation already in progress
```

一度、`launchctl unload` して、再度 `launchctl load` すればOK。

```
launchctl unload ~/Library/LaunchAgents/setenv.M2_HOME.plist 
launchctl load ~/Library/LaunchAgents/setenv.M2_HOME.plist 
```

## 参照 Reference
- [HowTo: Set an Environment Variable in Mac OS X - launchd.plist](http://www.dowdandassociates.com/blog/content/howto-set-an-environment-variable-in-mac-os-x-launchd-plist/)
    - Official Support ページにぱっとみ見当たらず、このページが一番すっきり説明している。
- [launchctl(1) Mac OS X Manual Page](https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/launchctl.1.html)

# Mac OS 10.8 (Mountain Lion), 10.9 (Mavericks)
* `/etc/launchd.conf` を使う
* `~/.MacOSX/environment.plist` は後述のように10.7 (Lion) 以前で有効。10.8 (Mountain Lion), 10.9 (Mavericks)では **使えない**。

## 設定手順 Procedure
- 設定ファイルを編集。etc 下なので sudoで。

```
$ sudo vi /etc/launchd.conf
```

- ファイル内容

```
setenv LANG ja_JP.UTF-8
```

## 注意 Notice
- 変更後、マシン再起動が必要
  - `~/.launchd.conf` はすでにdeprecated

## 参照 Reference
* launchd についてはこのあたり
  * [Mac Developer Library - About Daemons and Services](https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/Introduction.html)
      * [Creating Launch Daemons and Agents](https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html)


# Mac OS 10.7 (Lion) 以前
* `~/.MacOSX/environment.plist` を使う
* `/etc/launchd.conf` は前述のように10.8以降で有効。10.7 (Lion)では **使えない**。

## 設定手順 Procedure
- まず初期状態では、`.MacOSX` ディレクトリは存在しない

```
$ mkdir ~/.MacOSX
```

- 設定ファイルを編集。

```
$ vi ~/.MacOSX/environment.plist
```

- ファイルの中身はXMLファイル。以下のような書式。

```
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>LANG</key>
<string>ja_JP.UTF-8</string>
</dict>
</plist>
```

- ちなみにXMLなので、要素内で普通に改行が使える。JSONの値などを環境変数に持ちたい場合、改行つきの構造をそのまま設定できる。

```
<dict>
<key>FAVARITE_URL</key>
<string>
{
  "google" : "http://google.com",
  "twitter" : "http://twitter.com"
}
</string>
</dict>
</plist>
```


## 注意 Notice
* この設定はOSにログイン時に設定されるため、変更後は再度ログインが必要。マシンの再起動までは不要。