さまざまなプロジェクトのソースコードを扱っていると、プロジェクトに応じて環境変数を切り替えたいことがあります。もし現在のディレクトリに応じて環境変数が自動的に切り替わったら?
それを実現してくれる 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 | # direnv configuration |
設定ファイルを記述するためのエディターを環境変数EDITOR
に設定します。今回はvi
としました。続いてeval "$(direnv hook bash)"
で Bash のフックに direnv を登録します。
上記設定を読み込みます。
1 | source ~/.bash_profile |
利用するプロジェクトごとに環境変数を設定
環境変数を設定したいディレクトリで.envrc
ファイルを作り、export
で環境変数の定義を書きます。利用しているシェルの種類にかかわらず、このファイルは Bash の書式で記述します。
direnv edit [path]
でエディターを起動し、設定を保存します。
1 | $ cd ~/my-brilliant-project |
エディターを保存して終了すると、そのディレクトリに.envrc
ファイルが作られます。また以下のように設定を読み込んだとのメッセージが出力されます。環境変数を確認すると、確かに読み込まれています。
1 | direnv: loading .envrc |
ディレクトリを出ていくと、以下のようにアンロードしたとのメッセージが出力され、また入ると読み込まれます。ディレクトリに応じて自動的に環境変数が切り替わっているのがわかります。
1 | cd ../ |
あとは、必要なディレクトリごとに.envrc
を用意します。
なおdirenv edit
以外の方法で.envrc
が作られたり変更されると、はじめて.envrc
を読み込む際にエラーが表示されます。これはアーカイブやgit clone
などで.envrc
が作られた場合も同様ですし、他のユーザーが.envrc
を編集した(そのユーザーがdirenv edit
を使ったとしても)もエラーが表示されます。
これは自分が明示的に編集した.envrc
ではない場合に、自動で読み込むと危険だからです。
エラーが表示された場合は.envrc
に問題ないことを確認し、読み込む場合はdirenv allow
を実行します。
※ 一度direnv allow
しても、.envrc
が自分のdirenv edit
以外で書き変わると再エラー&確認が必要となります
1 | cd ~/my-splendid-project |
注意.envrc
に秘匿情報がある場合は、Git などのソースコード管理の対象にしないよう注意が必要です。
Shell のディレクトリ移動に応じて環境変数の定義を切り替えてくれる direnv、一度設定すれば後は無意識に切り替えてくれるので助かります。