シェルが /usr/bin の実行ファイルを使用し、/usr/local/bin の実行ファイルを使用しないのはなぜですか

シェルが /usr/bin の実行ファイルを使用し、/usr/local/bin の実行ファイルを使用しないのはなぜですか

与えられた条件:

/usr/local/bin/cmake
/usr/bin/cmake
$ cmake # runs /usr/bin/cmake

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

/usr/local/bin/cmakeなぜそうなるのでしょうか。また、入力時にシェルが実行可能ファイルを実行するようにするにはどうすればよいでしょうかcmake(エイリアスなどを使用せずに)。

答え1

問題は実行することで明らかになった

$ type -f cmake
cmake is hashed (/usr/bin/cmake)

そして、bashハッシュをクリアします

hash -d cmake

この後、cmake予想通りの解釈となりました。

答え2

同じシェル セッションの以前の時点で、 を使用しましたがcmake、その実行可能ファイルは で見つかりました/usr/bin

次に、別のcmake実行可能ファイルをインストールしました/usr/local/bin

シェルbashは、外部コマンドを使用する際に最初に見つけた場所をキャッシュします。つまり、次回同じコマンドを使用するときに実行ファイルの検索に手間がかかりません。この欠点は、検索をしなくて済むことです。また$PATH後で同じ名前の別の実行可能ファイルをインストールする場合、元の場所よりも前のディレクトリにインストールした場合でも同じです。

この問題の解決策は、bash保存されている実行可能ファイルのキャッシュされた場所を空にすることです。これは、シェルではhash -r(を使用して行われます。実行可能ファイルの場所だけを忘れるには、シェルでは(を使用します。rehashzshcmakehash -d cmakeunhash cmakezsh


この質問の以前のバージョンでは、さらに、 と の 2 つのコマンドtype cmakewhich cmake異なる結果を返す理由について疑問が投げかけられていました。 ではwhich cmake期待される結果 ( /usr/local/bin/cmake) が返されるのに対し、 ではtype cmake間違った結果 ( ) が返されるように見えました/usr/bin/cmake

その答えは、シェルが使用するコマンドの同じキャッシュされた場所を使用するtype組み込みコマンドであり、bashwhichない組み込みコマンドであるため、実行可能ファイルのキャッシュされた場所を使用することはできません。

この場合、は でwhich検索を行ったため、期待どおりの結果が返されましたが、実際にはcmake$PATH間違っている結果として、cmakeコマンドラインで実行すると、実際にはないそこから取得します/usr/local/bin(キャッシュのため、which気付かないでしょう)。

の歴史whichと、それを使用する際に注意すべき点の概要は、次のとおりです。「which」を使わないのはなぜですか? では、何を使うべきでしょうか?

関連情報