typeとwhichの違いって?
Linuxサーバ OS編。コマンドのパスの確認について。
以前whichとwhereisの違いって?という記事を書いたのが、そう言えばtypeという
コマンドがあったことを突然思い出した。
「コマンドのパスを調べるんだったらtypeでもいいんだった〜」・・・と思ったものの、
はて、typeコマンドの本来の意味はというと?
ちゃんと調べてみたら、やはり微妙に違っていた。
こちらによると、typeは「指定したコマンドがbashでどのように解釈されるかを調べるコマンド」
・・・ということだ。
少し説明すると、Linux上で使用するコマンドにも内部(ビルトイン)コマンドや外部
コマンドであったり、エイリアスであったりといろいろあり、typeはそういった名コマンド
の「正体」を確認できる、ということらしいのである。
えぇっ、そうだったの!?・・・自分、今まで知りませんでした。
そこで、改めていくつかのコマンドを対象に、which,whereis,typeを実行してみた。
以下のtypeの結果を見ると、cdはbashのビルトインコマンドであり、よってwhichを
実行してもPATHに定義されたディレクトリには存在しないことが分かる。
※ビルトインコマンドはファイルとして存在しない。
# which cd
/usr/bin/which: no cd in (/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin)
# whereis cd
cd: /usr/share/man/man1/cd.1.gz /usr/share/man/man1p/cd.1p.gz
# type cd
cd is a shell builtin
以下は標準的な出力パターンだろうか。外部コマンドだとこうなる?
# which lspci
/sbin/lspci
# whereis lspci
lspci: /sbin/lspci /usr/share/man/man8/lspci.8.gz
# type lspci
lspci is /sbin/lspci
以下を見ると、lsコマンドはエイリアスということが判明。
# which ls
alias ls=’ls –color=tty’
/bin/ls
# whereis ls
ls: /bin/ls /usr/share/man/man1/ls.1.gz /usr/share/man/man1p/ls.1p.gz
# type ls
ls is aliased to `ls –color=tty’
以下のtypeの結果、”hashed”ってなに?と思って調べたら・・・
# which whereis
/usr/bin/whereis
# whereis whereis
whereis: /usr/bin/whereis /usr/share/man/man1/whereis.1.gz
# type whereis
whereis is hashed (/usr/bin/whereis)
bashは コマンドの場所へ高速にアクセスするために、よく使用するパスをキャッシュ
にとっていて、ハッシュテーブルがそのキャッシュを登録しているそうだ。
(こちらを参照しました)
要するに上記でtypeコマンドを実行した時点で、whereisコマンドはハッシュテーブルに
存在している、ということだったらしい。
このキャッシュがどういうタイミングでクリアされるのかは不明。
一回ターミナルを閉じて再度 # type whereis としてみたら・・・
# type whereis
whereis is /usr/bin/whereis
と、標準的な出力結果になっていた。ちなみに、hashコマンドでハッシュテーブルの状態
を確認できる。キャッシュがクリアされていると、以下のようになる。
# hash
hash : hash table empty
何らかのコマンドがハッシュテーブルにキャッシュされていれば、以下のようになる。
$ hash
hits command
2 /bin/egrep
この段階で type egrepを実行すると、egrep is hashed(/bin/egrep)となる訳ですね。
ちなみにハッシュテーブルのキャッシュを明示的にクリアするには、$ hash -rを実行。
あああ、ハッシュテーブルがどうの、なんて考えてもいなかったのにまた思わぬところ
から深みに・・・いや、ひとつ物知りになれてラッキーと思うべきなのだろう、ここはw
何気に使っているコマンドでも、知っているつもりで知らないことは多々あるものだ。
まとめると、typeによってコマンドのパスが表示されることもあるけれど、本来の目的は
コマンドタイプを調べるもの、ってことなんですね。
なので、コマンドのパスを調べるならやはりwhichか、と。
追記
typeに-aオプションをつけて実行すると、シェルビルトインと同名のコマンドが存在
する場合、どちらも表示してくれる。
$ type -a kill
kill is a shell builtin
kill is /usr/bin/kill
kill is /bin/kill
関連記事
whichとwhereisの違いって?