isoppp

Macの環境変数の書き方を整理してみた

  • Bash

何かよくわからないまま放置してもあれなのでまとめ。 初めて書くので意味不明だったらごめんなさい!

201711更新: 記事自体の訂正とコメントから修正を反映しました

対象読者

export LANG=ja_JP.UTF-8
export PATH="$PATH:/sdk/androidSDK/sdk/platform-tools"
export PATH="$PATH:/sdk/androidSDK/sdk/tools"
export PATH=$PATH:`npm bin -g`
PATH=/bin:/usr/bin:/usr/local/bin:${PATH}

こういうのはとりあえずコピペで持ってきたら動くんだけど正直よくわかっていない。 (このコードは編集途中の問題のあるコードなので真似しないでください)

export PATH=$PATH:追加したいもののパス

とか書いてあるんだけどそれで動くのはいいけど なんでそれでいいのかが分からんのだよ。

という初心者向けです。

使用しているシェル

echo $SHELLと打つとパスから種類がわかるかと思います。 今回はbashとzshの説明となります。

  • bash macのデフォルトのターミナルの状態です。 この状態の方は今回は~/.bash_profileを編集します。

  • zsh ~/.zshenvを編集します。

上記ファイル以外にも設定がファイルが存在し、読み込まれる順番等がありますが、 説明が複雑になるため省略し、今回は上記のファイルを対象とします。 (※気になる方は bash_profile bashrc 等でぐぐると良いです)

上記ファイルは~//Users/ユーザー名のフォルダを 指すことからそのユーザーが使用する場合のパスの設定となります。 (このユーザーとはログインする時のユーザーと同じです)

コマンドの確認

この辺りを触るにあたって使用するコマンド等のまとめ。

echo $PATH 現在設定しているPATHの中身を表示します。

source ~/.bash_profile source ~/.zshenv 書き換えたファイルを読み込み設定を反映させます。 (ターミナルを再起動させても同様の効果があります。)

設定ファイル(.bash_profile/.zshenv)

このファイルは一体何なのだ

まずこのファイルの中身ですが、シェルスクリプトと呼ばれる スクリプトファイルです。.sh等拡張子が付いたものと同じ書式です。 このファイルがターミナル起動時に自動的に実行されています。

試しにPATHがうんたらと記載されているゾーンの下に echo $PATHと書いてsourceをするか、ターミナルを再起動してみてください。 そうするとパスが表示されるはずです。

ファイルの中身と同じように直接ターミナルでexport PATH=$PATH:追加したいもののパスを 実行しても実はパスが通りますが、これは再起動すると失われるため、 再起動しても再度同じようにパスが通っている状態にするため、 設定ファイルに記載します。

このファイルでやりたいこと

環境変数以外にも色々できますが、今回は環境変数の話なのでそこに絞ります。 このファイルを触る人の多くは 環境変数を設定する という人が多いと思います。

この環境変数を設定するという点についてですが、 command not foundみたいなログが出てコマンドを使いたいからパスを通さないといけない、 という人やANDROID_SDK等の環境変数のパスを設定しないといけないという人が多いでしょう。

その場合、まず上の コマンドを解消する場合は環境変数$PATHにパスを通す 何かのツールのために環境変数を通す場合は$XXXにパスを通す ※XXXはそれぞれツールで必要な環境変数名

書き方・読み方

export LANG=ja_JP.UTF-8
export PATH="$PATH:/sdk/androidSDK/sdk/platform-tools"
export PATH="$PATH:/sdk/androidSDK/sdk/tools"
export PATH=$PATH:`npm bin -g`
PATH=/bin:/usr/bin:/usr/local/bin:${PATH}

最初に書いてあるこのソースですが、問題がありまして、 最終的には別の形になっています。 (既に問題に気付けていた方にはこの記事は不必要だと思いますが…)

説明的にこちらのほうが良いので修正したファイルで説明します。

export LANG=ja_JP.UTF-8
export PATH=/bin:/usr/bin:/usr/local/bin
export PATH="$PATH:/sdk/androidSDK/sdk/platform-tools"
export PATH="$PATH:/sdk/androidSDK/sdk/tools"
export PATH="$PATH:`npm bin -g`"

設定方法ですが、 export Name=path1:path2:path3 という風に書いた場合export NameがNameという環境変数を設定する。 という意味になるので Nameという環境変数にpath1,path2,path3を設定した という意味になります。 実際にターミナルで直接上記コマンドを入力し、echo $Nameと打つと結果が確認できます。

若干exportをセットで書くのでややこしいですが、

SAMPLE=/path/sample/
export SAMPLE
echo $SAMPLE

これでSAMPLEという環境変数にパスがセットできます。 と書くとすっきりする人もいるかと思います。 最初に書いた export PATH=$PATH:/something/add/path このコマンドはまずexport PATHこの部分でPATHという環境変数を 設定している、ということが分かります。 次にその中身に関しては$PATHというのはPATHの変数を展開という意味ですので、

export PATH=/bin
export PATH=$PATH:/usr/bin

のように連続で定義する事も多いと思いますが、これはようするに

export PATH=/bin
export PATH=/bin:/usr/bin

と同じです。 パスの追加がよくexport PATH=$PATH:/something/add/path このように書かれているのはこういう風に連続で書いても、 前の物に影響を与えず追加できるからだと思います。

問題の解決

export LANG=ja_JP.UTF-8
export PATH="$PATH:/sdk/androidSDK/sdk/platform-tools"
export PATH="$PATH:/sdk/androidSDK/sdk/tools"
export PATH=$PATH:`npm bin -g`
PATH=/bin:/usr/bin:/usr/local/bin:${PATH}

このコード、実は編集途中のファイルだったのですが、何が問題だったかというと…

  1. 色々なコマンドの入っている最終行の部分がexportされていないので、色々なコマンドが実行できなくなります。

  2. さらにはこの場合パスも通っていないのでnpm bin -gの部分もコマンドがねえよって怒られます(ひどい)

  3. さらにさらにはこのコードは全てPATHに追加していくため、source ~/.zshenvする度にPATHの中身が増えていきます。

ちゃんと理解していない自分はなんでやー!となって、いい加減ちゃんと理解しようと思い立ちました。 そしてそしてそしてこれらが解消されたのが以下のコードです。

export LANG=ja_JP.UTF-8
export PATH=/bin:/usr/bin:/usr/local/bin
export PATH="$PATH:/sdk/androidSDK/sdk/platform-tools"
export PATH="$PATH:/sdk/androidSDK/sdk/tools"
export PATH="$PATH:`npm bin -g`"

先ず後ろでnpmを使うことから/bin /usr/bin等の基本のフォルダは頭にしてみました。 さらにはこの最初の部分では $PATHを継承しないことにより、一度初期化させています。 これで当然ですがnpmコマンドも正常に動作します。 先ほど問題だったsource ~/.zshenvを何度しても$PATHの中身は変わりません。 (おおなんということだ)

終わりに

ということで環境変数設定周りは理解してみると意外とシンプルな作りだったんだなという印象です。 同じような悩みで日々悶々としている人の助けになれれば幸いです。

初めての投稿なので読みにくい感じになってしまっているかもしれない点や、 説明しておきながら今日理解した程度のぺーぺーですので、 何かお気づきの点等ありましたら遠慮なくご指摘ください!

訂正(201711)

問題は把握していましたが、ストックが地味に増えていっているのでコメント頂いたのを機に、追記・訂正します。

export PATH=/bin:/usr/bin:/usr/local/bin

こちらのコードで作成したファイルから PATH を0ベースで再定義していますが、 MACでは初期に設定で設定されている PATH があり、その設定と比較すると不足していました。 確か ifconfig コマンド等が使えなくなります。

また、このデフォルト設定を無理に上書きするのはよろしくないので、初期化しないほうが良いです。そして初期化して設定しているパス /bin:/usr/bin:/usr/local/bin はデフォルトで設定されているようでしたので不要です。

OSのデフォルト設定の把握方法はこちらが分かりやすかったです。

最終的にはパスの設定の場合シンプルに追加していく形で良いと思います。

export LANG=ja_JP.UTF-8
export PATH="$PATH:追加したいパス"
export PATH="$PATH:追加したいパス"
export PATH="$PATH:追加したいパス"
...

※余談ですが、現在筆者は fish を使っています