direnv - .profileを散らかさない
direnv
コマンド …
direnv
はシェルの環境変数の管理器です。
現在のディレクトリによって、環境変数を読み込んだり読み戻したりするために、bashやzshやfishといったシェルにフックを掛けられます。
これにより、プロジェクト固有の環境変数を持たせることができ、「~/.profile」ファイルが散らかりません。
各プロンプトの前に、現在のディレクトリとその上位のディレクトリの.envrc
ファイルの存在がdirenvにより確認されます。
ファイルが存在するとき、bashの副シェルに読み込まれ、全てのエクスポートされた変数がdirenvに捕捉されて、現在のシェルで使えるようになります。
また、設定が外れた変数は削除されます。
direnvは単一の静的実行ファイルにコンパイルされるため、プロンプトが表示されるとき、存在を感じさせない程度には高速です。 また言語に依らないため、rbenv、pyenv、phpenv等に似たソリューションの構築に使えます。
$ cd ~/my_project
$ echo ${FOO-nope}
nope
$ echo export FOO=foo > .envrc
\.envrc is not allowed
$ direnv allow .
direnv: reloading
direnv: loading .envrc
direnv export: +FOO
$ echo ${FOO-nope}
foo
$ cd ..
direnv: unloading
direnv export: ~PATH
$ echo ${FOO-nope}
nope
direnvが適切に機能するためには、シェルにフックする必要があります。 それぞれのシェルには、独自の拡張の仕組みがあります。
以下の行を~/.bashrc
ファイルの末尾に加えてください。
eval "$(direnv hook bash)"
必ず、rvm、git-promptやその他のプロンプトを操作するシェルの拡張より後にくるようにしてください。
以下の行を~/.zshrc
ファイルの末尾に加えてください。
eval "$(direnv hook zsh)"
以下の行を$XDG_CONFIG_HOME/fish/config.fish
ファイルの末尾に加えてください。
direnv hook fish | source
Fishは3つのモードに対応しており、大域環境変数direnv_fish_mode
で設定できます。
set -g direnv_fish_mode eval_on_arrow # プロンプト、及び矢印ベースのディレクトリの変更でdirenvを開始(既定)
set -g direnv_fish_mode eval_after_arrow # プロンプト、及び実行コマンド前の矢印ベースのディレクトリの変更でのみdirenvを開始
set -g direnv_fish_mode disable_arrow # プロンプトでのみdirenvを開始。元々の動作と似た機能性です
以下の行を~/.cshrc
ファイルの末尾に加えてください。
eval `direnv hook tcsh`
以下を実行してください。
~> mkdir -p ~/.config/elvish/lib
~> direnv hook elvish > ~/.config/elvish/lib/direnv.elv
そして、以下の行を~/.config/elvish/rc.elv
ファイルに加えてください。
use direnv
以下の行を$PROFILE
に加えてください。
Invoke-Expression "$(direnv hook pwsh)"
以下の行を~/.murex_profile
に加えてください。
direnv hook murex -> source
direnv allow [rcへのパス]
: 与えられた.envrcや.envファイルを読み込むことを許可します。
direnv deny [rcへのパス]
: 与えられた.envrcや.envファイルの認可を失効させます。
direnv edit [rcへのパス]
:
rcへのパス、または現地点にある.envrc、ないし.envを$EDITORで開き、その後でファイルを読み込めるようにします。
direnv exec ディレクトリ コマンド [...引数]
:
ディレクトリで最初に見つかった.envrcないし.envを読み込んだ後でコマンドを実行します。
direnv export シェル
: .envrcないし.envを読み込み、エクスポートで使える差分を印字します。対応しているシェルは、bash,
zsh, fish, tcsh, elvish, pwsh, murex, json, vim, gha (GitHub Actions),
gzenv, systemdです。
direnv fetchurl <url> [<整合性ハッシュ>]
: 与えられたURLをdirenvのCASに取得します。
direnv help
: このヘルプを表示します。
direnv hook シェル
: シェルのフックを立ち上げるのに使います。
direnv prune
: 許可されたファイルのうち古いものを削除します。
direnv reload
: envの再読み込みを開始します。
direnv status
: デバッグ状態の情報を印字します。
direnv stdlib
: .envrcの実行の文脈で使える標準ライブラリを表示します。
direnv version
: バージョンを印字するか、VERSION_AT_LEASTよりdirenvが古いかどうかを判定します。
対象のフォルダにより、.envrc
ファイルを作ってexport(1)やunset(1)ディレクティブを加えてください。
次のプロンプトを見ると、.envrc
が阻まれたことでdirenvが文句を言っていることに気付きます。
これは安全のための仕組みであり、自動で新しいファイルを読み込むのを避けています。
さもなくば、プルした全てのgitリポジトリや、開封したtarアーカイブにより、その中にcd
したが最後、ハードドライブを消し去ってしまうことができるでしょうから。
ここでは何も悪いことは起きようがないことは確実です。
direnv allow .
と入力し、direnvが新しい環境を読み込む様子を見てください。
なお、.direnv edit .
は手軽なショートカットであり、$EDITORでファイルを開いてファイルの変更時間が変化したときに自動で再読込されます。
これで環境が読み込まれました。
ディレクトリの外にcd
すると、自動で読み戻されることに気付かれるでしょう。
cd
で中に戻ると、再び読み込まれます。
以上が基本的な仕組みであり、これを使うと色々と工夫できるでしょう。
手作業で変数をエクスポートするのは、ちょっとした作業の繰り返しになってしまいます。
そこでdirenvでは、いろいろな補助関数が提供されており、.envrc
ファイルの文脈で使えるようになっています。
詳しくはdirenv-stdlib(1)のmanページをご確認ください。
また、$XDG_CONFIG_HOME/direnv/direnvrc
ないし$XDG_CONFIG_HOME/direnv/lib/*.sh
ファイルの中に、独自の拡張を定義することもできます。
きっとここまでで始めてみる分には充分でしょう。
XDG_CONFIG_HOME
:既定で$HOME/.config
です。
XDG_DATA_HOME
:既定で$HOME/.local/share
です。
$XDG_CONFIG_HOME/direnv/direnv.toml
:Direnvの構成です。direnv.toml(1)を参照。
$XDG_CONFIG_HOME/direnv/direnvrc
:.envrc
の前に、毎回読み込まれるBashコードです。個人用の拡張に好適です。
$XDG_CONFIG_HOME/direnv/lib/*.sh
:.envrc
の前に毎回読み込まれるBashのコードです。サードパーティの拡張に好適です。
$XDG_DATA_HOME/direnv/allow
:どの.envrc
ファイルがdirenv allow
されたかを記録しているところです。
不具合の報告、貢献、フォークを歓迎します。
不具合やその他の議論は全て、 http://github.com/direnv/direnv/issues でされています
ウィキもあり、使用しているパターン、その他のコツやトリックを共有したりすることができます:https://github.com/direnv/direnv/wiki
もしくは、チャットをされる方はFreeNodeの#direnvチャンネルにお立ち寄りください。
MIT licence - Copyright (C) 2019 @zimbatm and contributors
direnv-stdlib(1), direnv.toml(1), direnv-fetchurl(1)