which コマンド
which コマンドについて
which コマンドは、あってあたりまえで、特に詳しく調べることもしなかった。今回はwhich コマンドを見直してみることにする。
そもそも which コマンドって?
which コマンドは、指定されたコマンドがPATHの何処に出現するか調べてくれる。
利用場面は、此のコマンドどこにあるんだっけ?ときにつかう。which PATH is this comand in ?
の疑問に答えてくれる。
たとえば、次のように使う。
takuya@~$ which bash /usr/local/bin/bash
which コマンドを更に追求する
「此のコマンドどこに?」の「このコマンド」の定義を広くする。何もしないと、PATHを探すのだ。だけれどもコマンドはファイルとは限らない。funtion
alias
もコマンドとして機能する.これらを探せるのが which
だけど、その検索範囲は、非常に限られている。詳細に指定してあげなくてはいけない。
which ls
これだと PATHから探してくれるだけだ。
このls は何の? which is ls
そのため、ls といっても、実際に使っているls
はどれだ?。この目的だと、type
コマンドを用いて確認することが多いのだ。
takuya@~$ type ls ls は `ls --color=auto --time-style=long-iso ' のエイリアスです
なので、which を使う場面は限られて、殆どの場合 type
コマンドで済ませることが多いのだ。というか、実直な感想を言えば、type 万能。type 万歳。でも今回は、コレを which でやることが出来ることを知ったのでマトメていくのだ。
which コマンドで 検索に alias も含める。
エイリアスを含めるには、which に標準出力で エイリアスの一覧を与えて、 --read-alias / -i
オプションを付けるのだ。
alias | which --read-alias ls
実行結果
takuya@~$ alias | which --read-alias ls alias ls='ls --color=auto --time-style=long-iso ' /Users/takuya/.bin/ls
which コマンドの検索に function も含める。
function を含めることも出来る。 declare -f
で関数一覧を取り出して、--read-functions
を使ってwhich の検索に関数を含めることが出来る。
declare -f | which --read-functions find
実行例
takuya@~$ declare -f | which --read-functions find -a find () { #略 }
alias も function もどちらも検索対象にしたい。
alias も function も PATH もまとめて、全てからからコマンドの存在を調べたい。 この意図だと ( alias; declare )
とサブシェルで2つを同時に与える。
(alias;declare -f) | which --read-alias --read-functions--read-functions # またはグループ化で。 { alias;declare -f; } | which --read-alias --read-functions find
実行例
takuya@~$ (alias;declare -f) | which --read-alias --read-functions ls alias ls='ls --color=auto --time-style=long-iso ' /Users/takuya/.bin/ls
ここまでやるなら、もう type 使うよね?ねー
同名のコマンドをすべて列挙する
-a
オプションを付ける。
実行例
takuya@~$ which -a bash /usr/local/bin/bash /bin/bash
コマンドが何処にあるか調べる意図だと -a
のオプションが一番良いね。
ぶっちゃけ type でよくね?
調べるだけなら、type でいいんです。type でね
個人的には、 which は コマンドの探索 。 type はコマンドの判別に使っています。ただ、使い分けなくても which だけでも十分用途に足りるんだ。と感心してました。
which の活用法
which は type と違い、コマンドのフルパスが返ってくる効果があります。これを利用して、フルパス指定コマンドで場所がわからないときなどにとりあえず which しておけば便利です。。
$(which find) -type d
まぁこちらも env
コマンドがあるから env でもいいですがね. env だと引数を与えられませんし、そもそも実行方式が違うんだ。
## できる $(env find) $(which find) -type d $(which find) -type d ~/Desktop ## できない $(env find) -type d ~/Desktop
which だけじゃわからないもの
which だけじゃ足りないことがある。
関数はわかりません、シンボリックリンクはたどってくれません。
関数は見えない。
takuya$ function grep { echo ... ; } takuya$ which grep /bin/grep
関数は見えないので前述の通り type を使いましょう。
フルパスは見えない。
シンボリックリンクされているコマンドの実体パスはもちろん見えません。 home brew のようにコマンドファイルがsym link にされていの時があるのだ。
takuya@~$ which gls /usr/local/bin/gls takuya@~$ realpath /usr/local/bin/gls /usr/local/Cellar/coreutils/8.26/bin/gls
このように実体ファイルを知りたいときには、 realpath ( または readink) を重ねがけする必要がある。
readlink $(which gls)
これはめんどくさいので、ショートカットにしておくと便利
function which-realpath(){ realpath $( which $@ ) }
which -a で全部
あれ、確かインストールしたはずだけど、パスがおかしいのかとか。同名のコマンドがいくつもあるときに、パスの優先順位を調べるとき whereis / which --all が便利です。
which -a node which --all node
なお類似にコマンドに whereis があります。
whereis というコマンドでも類似のことが出来ます。
ただ、whereis は おもに locate の代わりになります。コマンドそのものを探すわけではありません。
windows だと where ですね。
whatis / who / which / whereis / whoami / while など whから始まる コマンドは何かと便利だ。
参考資料
- man which ( GNU which )
関連記事
which コマンドでPATHにある同名のコマンドを全部列挙する - それマグで!
2019-08-23
記述を修正