Shell の作業ディレクトリごとに自動で環境変数を設定する

さまざまなプロジェクトのソースコードを扱っていると、プロジェクトに応じて環境変数を切り替えたいことがあります。もし現在のディレクトリに応じて環境変数が自動的に切り替わったら?
それを実現してくれる direnv を紹介します。

The Twelve-Factor App (日本語訳) などでも取り上げられているように、アプリやシステムの設定に環境変数を使うことが多いです。

その環境変数を毎回設定するにしても手間ですし忘れがちです。また .bashrc などに全部設定しロードしておくこともできますが、プロジェクトが増えてくると煩雑になり困ります。

そのような時に使えるのが direnv です。対応しているのが “bash, zsh, tcsh, fish shell and elvish - direnv“ とのことなので、Linux/Mac そして WSL(Windows Subsystem for Linux) が中心となりますが、環境変数を自動的に切り替えてくれる素晴らしい機能を提供してくれます。

環境
本記事の開発環境は以下となります。

  • Windows 10 64bit + WSL Ubuntu 18.04.1 LTS
  • Bash 4.4.19 (WSL Ubuntu)
  • direnv/direnv 2.20.0

参考情報

direnv とは

Shell 用の環境スイッチャーで、現在のディレクトリに応じて環境変数をロードまたはアンロードしてくれます。

まさに “~/.profile ファイルを乱雑にすることなくプロジェクト固有の環境変数を使用できます - direnv“ とのこと。

もう、この一文で語りつくされているのではないでしょうか。(私の序文は長くて冗長だった。。。)

direnv の導入

WSL Ubuntu にはデフォルトで入っていないのでインストールします。
※ 各環境に合わせたインストールおよび設定は Install - direnv/direnv をご確認ください

1
$ sudo apt install direnv

~/.bashrc に以下の設定をします。
※ ただし WSL Ubuntu の場合は ~/.bashrc がデフォルトで読み込まれないので、今回は ~/.bash_profile に設定

1
2
3
# direnv configuration
export EDITOR=vi
eval "$(direnv hook bash)"

設定ファイルを記述するためのエディターを環境変数 EDITOR に設定します。今回は vi としました。続いて eval "$(direnv hook bash)" で Bash のフックに direnv を登録します。

上記設定を読み込みます。

1
$ source ~/.bash_profile

利用するプロジェクトごとに環境変数を設定

環境変数を設定したいディレクトリで .envrc ファイルを作り、export で環境変数の定義を書きます。利用しているシェルの種類にかかわらず、このファイルは Bash の書式で記述します。

direnv edit [path] でエディターを起動し、設定を保存します。

1
2
3
$ cd ~/my-brilliant-project
$ direnv edit .
export MSG=Hello

エディターを保存して終了すると、そのディレクトリに .envrc ファイルが作られます。また以下のように設定を読み込んだとのメッセージが出力されます。環境変数を確認すると、確かに読み込まれています。

1
2
3
4
5
direnv: loading .envrc
direnv: export +MSG

$ echo $MSG
Hello

ディレクトリを出ていくと、以下のようにアンロードしたとのメッセージが出力され、また入ると読み込まれます。ディレクトリに応じて自動的に環境変数が切り替わっているのがわかります。

1
2
3
4
5
6
7
8
9
10
11
12
$ cd ../
direnv: unloading

$ echo ${MSG-unloaded}
unloaded # アンロードされている

$ cd ~/my-brilliant-project
direnv: loading .envrc
direnv: export +DEBUG +MSG

$ echo ${MSG-unloaded}
Hello # .envrc が読み込まれている

あとは、必要なディレクトリごとに .envrc を用意します。

なお direnv edit 以外の方法で .envrc が作られたり変更されると、はじめて .envrc を読み込む際にエラーが表示されます。これはアーカイブや git clone などで .envrc が作られた場合も同様ですし、他のユーザーが .envrc を編集した(そのユーザーが direnv edit を使ったとしても)もエラーが表示されます。

これは自分が明示的に編集した .envrc ではない場合に、自動で読み込むと危険だからです。
エラーが表示された場合は .envrc に問題ないことを確認し、読み込む場合は direnv allow を実行します。
※ 一度 direnv allow しても、.envrc が自分の direnv edit 以外で書き変わると再エラー&確認が必要となります

1
2
3
4
5
6
$ cd ~/my-splendid-project
direnv: error .envrc is blocked. Run `direnv allow` to approve its content.

$ direnv allow
direnv: loading .envrc
direnv: export +MSG

注意
.envrc に秘匿情報がある場合は、Git などのソースコード管理の対象にしないよう注意が必要です。


Shell のディレクトリ移動に応じて環境変数の定義を切り替えてくれる direnv、一度設定すれば後は無意識に切り替えてくれるので助かります。