探し物は何ですか?(Linuxコマンドパス検索「which」他編)

こんにちは。技術部3課運用チームのftaniです。

今回は先日の「探し物は何ですか?(Linuxファイル検索編)」と
やや近い内容ですが、

 ○○コマンドの絶対パスは?

というケースで使うコマンドになります。

 which コマンド名
 whereis コマンド名

でコマンドの絶対パスを調べます。

コマンドの絶対パスを調べるという点では、whichとwhereis
どちらも同じですが、whereisはmanページのファイルパスなども
表示してくれます。

では早速使ってみましょう。

$ which perl
/usr/bin/perl

$ whereis perl
perl: /usr/bin/perl /usr/share/man/man1/perl.1.gz

ここの環境では「perl」は「/usr/bin」にあるようですね。

複数のパスに「perl」が存在している場合はどうなるか、
ちょっと試してみましょう。

$ echo $PATH
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/ftani/bin

パスが通っているホームディレクトリ以下にダミーの「~/bin/perl」を
置いてみます。

$ which perl
/usr/bin/perl

$ whereis perl
perl: /usr/bin/perl /usr/share/man/man1/perl.1.gz

同じ結果ですね。

PATHを入れ替えて「~/bin」が最優先ならどうでしょう。

$ echo $PATH
/home/ftani/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin

では、whichから

$ which perl
/home/ftani/bin/perl

割と想像通りの結果です。whereisはどうでしょう?

$ whereis perl

perl: /usr/bin/perl /usr/share/man/man1/perl.1.gz
 

んっ!?


whereisは環境変数「PATH」を参照していないのでしょうか?

「$ man whereis」すると「BUGS」に

 whereis has a hard-coded path, so may not always find
 what you’re look-ing for.

 意訳
 whereisはハードコードされたパスを使うから、探し物は見つからないかも。

という記載が、、、納得ですが、ソースも見ときましょう。

手元環境のwhereisは「rpm -qf /usr/bin/whereis」で探すと

 util-linux-ng-2.17.2-12.14.el6.x86_64

に含まれているようです。今回は、

 https://www.kernel.org/pub/linux/utils/util-linux/v2.17/

からソースを入手し、「misc-utils/whereis.c」をざっと眺めてみると、

void
lookbin(char *cp) {
        if (Bflag == 0)
                find(bindirs, cp);
        else
                findv(Bflag, Bcnt, cp);
}

といった記述があり、対応する「bindirs」は以下のように固定的な
パスになっていますので、やはり環境変数「PATH」は見ていないようです。

 

 

static char *bindirs[] = {
   "/bin",
   "/usr/bin",
  :
   "/opt/*/bin",

        0
};

また、最新の「util-linux-2.25」のソース「misc-utils/whereis.c」の
コメント欄には
 

 * 2011-08-12 Davidlohr Bueso <dave@gnu.org>
 * – added $PATH lookup


との記述があり、だいぶ前から環境変数「PATH」も検索対象になって
いるようですね。


今回はこの辺で。
 

Share on Facebook0Tweet about this on Twitter0Share on Google+0Share on LinkedIn0Pin on Pinterest0