node のバージョン管理ツール ndenv をインストールすると初期化スクリプト内部に下記のコマンドを追加します。
export PATH="$HOME/.ndenv/bin:$PATH" eval "$(ndenv init -)"
せっかくなので下記のコマンドがどのように解釈されるのかというところを追ってみることにしました。
検証は osx 上で実施しています。各環境で差異があると思われますので注意してください。
evalされるスクリプトを確認する
まずはターミナル上でコマンドを実施してその内容を確認してみます
$ ndenv init - source "/Users/user/.ndenv/libexec/../completions/ndenv.zsh" ndenv rehash 2>/dev/null ndenv() { typeset command command="$1" if [ "$#" -gt 0 ]; then shift fi case "$command" in rehash|shell) eval "`ndenv "sh-$command" "$@"`";; *) command ndenv "$command" "$@";; esac }
typesetとは
まず man コマンドを用いて調べるが、ドキュメントが存在しない。
なのでググりながら色々試して把握してみる。
どうやら typeset は変数の宣言を行うコマンドであるが、特徴的なのが変数に実際に格納されたデータとは別に型の情報を持つことができる。
これはイメージとしては高級なプログラミング言語で変数に型があるような感覚と少し似ている。
確認してみよう。
例えばシェル上で次のコマンドを実施する
$ hoge=fuga
このあとに typeset コマンドを実施することですべての変数をリスト形式で表示する
$ typeset ... hoge=fuga ...
おそらく上記のような出力がされるのだが、出力された他の項目と比較してみると若干様子が異なる。
そう。型情報がない。
そこでこのhoge変数に型情報を宣言してみる。-u というオプションを指定することで「小文字を大文字に変換する」という型を宣言することになる。
$ typeset -u hoge
このあとに先と同様に変数リストを表示してみる
$ typeset ... uppercase hoge=fuga ...
再度typesetコマンドを実施すると上記のように uppercase という型が宣言されていることがわかる
ここで echo コマンドを実施してみると
$ echo $hoge FUGA
と出力される文字が大文字に変換されて出力されることがわかる。
これは echo コマンドが typeset で宣言されている型の情報まで解釈してくれ、実態として持っている fuga という値を uppercase という型に準じて大文字に変換して表示してくれている。
というわけで本筋に戻ると、下記のようなコマンドでした。
typeset command
これは単純に command という変数を宣言しているに過ぎないです。
なので、なくても困らないのではないかなと思います。
次に行きましょう。
command="$1" if [ "$#" -gt 0 ]; then shift fi
こちらは単純に第一引数を command 変数に格納しているだけです。
続いて command 変数に格納した第一引数が不要になったので破棄しています。
最後の箇所ですが、コマンドに応じて分岐した処理を実施します。
case "$command" in rehash|shell) eval "`ndenv "sh-$command" "$@"`";; *) command ndenv "$command" "$@";; esac
例えば rehash を実施すると、下記のコマンドの結果を評価するものと同等の内容になります
$ ndenv sh-rehash hash -r 2>/dev/null || true
hashコマンドはシェルが記憶しているコマンドをキャッシュしています。
-r オプションはキャッシュされた内容を削除します。そうすることによってキャッシュされたコマンドのパスをクリアすることができます。
また環境によると思いますが動作環境では hash -r したあとにコマンドを実施してみると、コマンドは普通に実行できます。
これはおそらく hash -r で削除したんだけれども、コマンドを実施する時点ではまた環境変数 PATH をもとにコマンドを探索するような処理が走っているのかなと考えられます。
何れにせよ。ndenv rehash のコマンドはキャッシュされた node コマンドのパスのクリアができることがわかりました。
command はそのまま ndenv へと引数を渡しつつコマンドを実施することがわかりました。
コメントを残す