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、一度設定すれば後は無意識に切り替えてくれるので助かります。