30歳からのプログラミング

30歳無職から独学でプログラミングを開始した人間の記録。

direnv を使った環境変数の管理

以前、Node.jsで環境変数を管理する方法として、dotenvについて書いた。

numb86-tech.hatenablog.com

だがdirenvを使えばもっと簡単に環境変数を管理できることを知った。

github.com

この記事の内容はmacOS10.13.5で動作確認している。

セットアップ

homebrewを使っていれば非常に簡単に出来る。

  1. homebrewでインストール
  2. ~/.bashrceval "$(direnv hook bash)"と書き込む
  3. 書き込んだ内容を反映させる
$ brew install direnv
$ cat >> ~/.bashrc
eval "$(direnv hook bash)"
^C
$ source ~/.bashrc

これで使えるようになった。

使い方

.envrcに、使いたい環境変数を書いていく。
書き方はexport 環境変数名=値
こうすると、.envrcが置いてあるディレクトリ以下でその環境変数を使えるようになる。

例として、値がhoge環境変数HOGEを設定してみる。

まず、HOGEが存在しないことを確認。

$ echo ${HOGE-nope}
nope

次に、.envrcを作成してexport HOGE=hogeと書き込む。
.envrcを作成したり編集したりするとエラーが出ることがあるので、そのときは$ direnv allowを実行する。

$ echo export HOGE=hoge > .envrc
direnv: error .envrc is blocked. Run `direnv allow` to approve its content.
$ direnv allow
direnv: loading .envrc
direnv: export +HOGE

これでHOGEを使えるようになったはずなので、確認してみる。

$ echo ${HOGE-nope}
hoge

対象となるのは.envrcが置かれているディレクトリ以下なので、他の場所には影響を与えない。

$ cd ../
direnv: unloading
$ echo ${HOGE-nope}
nope

下の階層にも.envrcを置けばその内容が採用される。
上位にある.envrcは無視される。

試しにまず、先程の.envrcFUGAを追加してみる。

$ echo export FUGA=fuga >> .envrc
direnv: loading .envrc
direnv: export +FUGA +HOGE
$ echo ${HOGE-nope}
hoge
$ echo ${FUGA-nope}
fuga

ディレクトリに移動してみるが、親ディレクトリにある.envrcの内容が使われている。

$ mkdir child && cd child
$ echo ${HOGE-nope}
hoge
$ echo ${FUGA-nope}
fuga

ディレクトリに.envrcを作成しFUGAについて設定する。
そうすると、その内容が反映される。

$ echo export FUGA=child > .envrc
direnv: error .envrc is blocked. Run `direnv allow` to approve its content.
$ direnv allow
direnv: loading .envrc
direnv: export +FUGA
$ echo ${FUGA-nope}
child

ではHOGEはどうなっているのかというと、存在しないことになっている。

${HOGE-nope}
nope

つまり、子ディレクトリにある.envrcが採用され、親ディレクトリの.envrcは無視される。

プログラムからの利用

.envrcに書いてあるものは他の環境変数と同じように扱われるので、プログラムのなかで問題なく取得することが出来る。
dotenvと違ってnpmモジュールをインストールする必要がないし、言語をまたがって使用することが出来る。

例として、Node.jsとRubyで使えることを確認してみる。
それぞれ以下の内容で、test.jstest.rbというファイルを作る。

console.log(process.env.SHELL);
console.log(process.env.HOGE);
puts ENV['SHELL']
puts ENV['HOGE']

確認のため、.envrcを削除して環境変数HOGEが存在しない状態に戻す。
この状態でそれぞれのプログラムを実行すると、最初から設定されているSHELLは取得できるが、HOGEは取得できない。存在しないので当然だが。

$ rm .envrc 
direnv: unloading
$ echo ${HOGE-nope}
nope
$ node test.js
/bin/bash
undefined
$ ruby test.rb
/bin/bash

HOGEを用意した上でプログラムを実行すると、正しく取得できていることが分かる。

$ echo export HOGE=hoge > .envrc
direnv: loading .envrc
direnv: export +HOGE
$ echo ${HOGE-nope}
hoge
$ node test.js
/bin/bash
hoge
$ ruby test.rb
/bin/bash
hoge

Gitの管理から外す

環境変数にはアクセスキーなどのセンシティブな内容を入れることが多いはずなので、.gitignoreで指定するなどして、慎重に管理する。