Mein `which` Befehl kann (manchmal) falsch sein?

17

Ich habe die letzte Emacs-Version aus dem Quellcode (v24.2) kompiliert, da die auf meinem Computer installierte Version für mich (ziemlich) alt ist (v21.3). Ich habe das übliche getan:

$configure --prefix=$HOME
make 
make install

Jetzt teste ich Emacs und stelle fest, dass die vorherige Version immer noch gestartet wird ... während mein $HOME/binPfad das System überschreiben soll (da er in meiner .bashrcDatei vor $ PATH steht ).

Mein erster Gedanke war, die whichBefehlsausgabe zu sehen . Und Überraschung, es gibt den Weg zu den neuen Emacs. Ich kann nicht verstehen, wo hier die Diskrepanz ist. In der gleichen Sitzung sind hier die verschiedenen Ausgaben:

$ emacs --version
GNU Emacs 21.3.1

$ `which emacs` --version
GNU Emacs 24.2.1

Ich habe keinen Alias ​​mit Emacs. Überhaupt.

$ alias | grep emacs
$

Irgendeine Idee, was bitte los ist?

Yves Baumes
quelle
was kommt welcher emacs zurück?
Ulrich Dangel

Antworten:

29

Die drei Möglichkeiten, die mir in den Sinn kommen:

  • Es existiert ein Alias ​​für emacs(den Sie überprüft haben)
  • Eine Funktion existiert für emacs
  • Die neue emacsBinärdatei befindet sich nicht in der PATH-Hash-Tabelle Ihrer Shell.

Sie können überprüfen, ob Sie eine Funktion haben emacs:

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

Und entferne es:

unset -f emacs

Ihre Shell hat auch eine PATH-Hash-Tabelle, die einen Verweis auf jede Binärdatei in Ihrem PATH enthält. Wenn Sie eine neue Binärdatei mit demselben Namen wie eine an anderer Stelle in Ihrem PATH vorhandene Binärdatei hinzufügen, muss die Shell durch Aktualisieren der Hashtabelle informiert werden:

hash -r

Zusätzliche Erklärung:

which kennt sich mit Funktionen nicht aus, da es sich nicht um eine eingebaute Bash handelt:

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

Dieses Skript demonstriert das neue Verhalten von binären Hashtabellen.

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

Obwohl ich es nicht aufgerufen habe, which catwürde es immer das erste catin meinem PATH zurückgeben, da es nicht die Hash-Tabelle der Shell verwendet.

mrb
quelle
1
Hier gibt es zwar gute Informationen, aber es fehlt der typeBefehl.
Jordan
Danke, ich hatte das gleiche Problem mit einer frisch kompilierten Version von sqlite3, was mich zum Narren machte (was tatsächlich den richtigen Pfad zurückgab, aber die Shell rief nicht das richtige sqlite3-cli auf). hash -rhabe mein Problem behoben.
29.09.18 Uhr
12

Ja, benutze nicht welche :

  • Auf einigen Systemen handelt es sich um einen externen Befehl, der als csh-Skript implementiert ist und möglicherweise eine Konfiguration liest, die das ändert PATH.
  • Dafür gibt es ein eingebautes. Zwei sogar: typeund command. Der POSIX-Weg:

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

    In bash können Sie auch type -p emacsnur den Pfad eines externen Befehls anzeigen.

Allerdings ist hier whicheigentlich richtig. Bash speichert Informationen über die Position eines Befehls im Speicher, damit er den Befehl beim nächsten Mal schneller ausführen kann. Sie haben eine neue emacsausführbare Datei auf Ihrem installiert PATH, aber Bash hat immer noch den alten Speicherort im Cache. Führen Sie hash emacsden Befehl aus, um emacserneut nachzuschlagen oder hash -rden Cache zu leeren.

Gilles 'SO - hör auf böse zu sein'
quelle
1

Haben Sie sich abgemeldet und angemeldet, damit Ihre aktualisierte .bashrcAnmeldedatei erneut gelesen wird? Wenn nicht, wurde die Umgebung Ihrer aktuellen Sitzung nicht aktualisiert.

JRFerguson
quelle
Wenn das der Fall `which emacs` --versionwäre , würde das stimmen emacs --version, da whichsein PATH von der aktuellen Shell erbt.
mrb
@ Mrb: Punkt gut getroffen.
JRFerguson