ディレクトリごとに環境変数を切り替えたいというユースケースはよくありますが、それを実現してくれるのが direnv です。
ぼくもこの direnv を利用して、AWS アカウントごとのアクセスキーを切り替えたりしています。
direnv は通常、各シェルの cd
の実行をフックする形で動きます。しかし、シェルスクリプトの中でこれを実現できない。どうやるものかと思っていたら、最終的には direnv export ${SHELL}
を呼び出せば良いということに気付きました。
direnv のセットアップは eval $(direnv hook ${SHELL})
で実行します。direnv hook zsh
の出力をみてみましょう。
$ direnv version 2.22.0 $ direnv hook zsh _direnv_hook() { trap -- '' SIGINT; eval "$("/usr/local/bin/direnv" export zsh)"; trap - SIGINT; } typeset -ag precmd_functions; if [[ -z ${precmd_functions[(r)_direnv_hook]} ]]; then precmd_functions=( _direnv_hook ${precmd_functions[@]} ) fi typeset -ag chpwd_functions; if [[ -z ${chpwd_functions[(r)_direnv_hook]} ]]; then chpwd_functions=( _direnv_hook ${chpwd_functions[@]} ) fi
precmd_functions
が出てきますが、これはプロンプト表示前を hook して実行される zsh の function 配列です。
このため、zsh だと _direnv_hook
をディレクトリ変更都度に実行していることがわかります。
さらに、本質的な処理は /usr/local/bin/direnv export zsh
のみであることもわかります。
結果として、シェルスクリプトで cd
する際、cd
の場合に以下のような function を実行すれば良いです。
function direnv_cd() { cd "$1" eval "$(direnv export bash)" } direnv_cd /path/to/destDir