それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

which コマンドを見直してみる。which コマンドの活用法

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

記述を修正