私の `which`コマンドは間違っているかもしれません(時々)?


17

私のマシンにインストールされているバージョンは(非常に)古い(v21.3)ため、ソースコード(v24.2)から最後のemacsバージョンをコンパイルしました。私はいつもやった:

$configure --prefix=$HOME
make 
make install

今、私はemacsをテストしており、以前のバージョンをまだ起動していることに気付きました...私の$HOME/binパスはシステムのものをオーバーライドすることになっています(.bashrcファイルの$ PATHに追加されているため)。

私の最初の考えは、whichコマンドの出力を見ることでした。そして驚いたことに、これは新しいemacsへのパスを提供します。ここで矛盾がどこにあるか理解できません。同じセッションでの出力は次のとおりです。

$ emacs --version
GNU Emacs 21.3.1

$ `which emacs` --version
GNU Emacs 24.2.1

emacsに関係するエイリアスはありません。まったく。

$ alias | grep emacs
$

何が起こっているのでしょうか?


どのemacsは何を返しますか?
ウルリッヒダンゲル

回答:


29

私に思い浮かぶ3つの可能性:

  • emacs(チェックした)のエイリアスが存在します
  • 次の機能が存在します emacs
  • 新しいemacsバイナリは、シェルのPATHハッシュテーブルにありません。

機能があるかどうかを確認できますemacs

bash-3.2$ declare -F | fgrep emacs
declare -f emacs

そしてそれを削除します:

unset -f emacs

シェルには、PATH内の各バイナリへの参照を含むPATHハッシュテーブルもあります。PATHの他の場所にある既存のバイナリと同じ名前の新しいバイナリを追加する場合は、ハッシュテーブルを更新してシェルに通知する必要があります。

hash -r

追加の説明:

which bashビルトインではないため、関数については知りません。

bash-3.2$ emacs() { echo 'no emacs for you'; }
bash-3.2$ emacs
no emacs for you
bash-3.2$ which emacs
/usr/bin/emacs
bash-3.2$ `which emacs` --version | head -1
GNU Emacs 22.1.1

このスクリプトでは、新しいバイナリハッシュテーブルの動作が示されています。

bash-3.2$ PATH=$HOME/bin:$PATH
bash-3.2$ cd $HOME/bin

bash-3.2$ cat nofile
cat: nofile: No such file or directory
bash-3.2$ echo echo hi > cat
bash-3.2$ chmod +x cat
bash-3.2$ cat nofile
cat: nofile: No such file or directory

bash-3.2$ hash -r
bash-3.2$ cat nofile
hi
bash-3.2$ rm cat
bash-3.2$ cat nofile
bash: /Users/mrb/bin/cat: No such file or directory

bash-3.2$ hash -r
bash-3.2$ cat nofile
cat: nofile: No such file or directory

私はそれを呼び出さなかったが、シェルのハッシュテーブルを使用しないため、which cat常にcatPATH の最初を返します。


1
ここには良い情報がありますが、typeコマンドを逃しています。
ヨルダン

おかげで、私はsqlite3のコンパイルされたばかりのバージョンで同じ問題を抱えていました。hash -r私の問題を修正しました。
mpm

12

はい、どちらも使用しないください

  • 一部のシステムでは、それはcshスクリプトとして実装された外部コマンドであり、.shを変更する構成を読み取る場合がありますPATH
  • そのためのビルトインがあります。2、偶数:typeおよびcommand。POSIXの方法:

    command -v emacs       # machine-readable format
    type emacs             # human-only format

    bashではtype -p emacs、外部コマンドのパスのみを表示するためにも使用できます。

しかし、ここでwhichは実際に正しいです。Bashはコマンドの場所に関する情報をメモリに保持するため、次回コマンドをより高速に実行できます。に新しいemacs実行可能ファイルをインストールしましたPATHが、bashのキャッシュにはまだ古い場所があります。実行hash emacsしてemacs再度検索するかhash -r、キャッシュを空にします。


1

更新された.bashrcログインファイルを再読み込みするために、ログアウトしてログインしましたか?そうでない場合、現在のセッションの環境は更新されていません。


その場合、現在のシェルからPATHを継承するため、`which emacs` --versionに同意します。emacs --versionwhich
-Mrb

@mrb:よく考えてください。
JRFerguson
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.