Il mio comando `quale` potrebbe essere sbagliato (a volte)?


17

Ho compilato l'ultima versione di emacs dal codice sorgente (v24.2) perché la versione installata sul mio computer è (abbastanza) vecchia per me (v21.3). Ho fatto il solito:

$configure --prefix=$HOME
make 
make install

Ora sto testando emacs e mi sono reso conto che lancia ancora la versione precedente ... mentre il mio $HOME/binpercorso dovrebbe sovrascrivere quello di sistema (dal momento che è anteposto a $ PATH nel mio .bashrcfile).

Il mio primo pensiero è stato vedere l' whichoutput del comando. E sorpresa, dà il percorso ai nuovi emacs. Non riesco a capire dove sia la discrepanza qui. Nella stessa sessione ecco i diversi output:

$ emacs --version
GNU Emacs 21.3.1

$ `which emacs` --version
GNU Emacs 24.2.1

Non ho alias che coinvolgono emacs. Affatto.

$ alias | grep emacs
$

Qualche idea di cosa stia succedendo per favore?


cosa restituisce quali emacs?
Ulrich Dangel,

Risposte:


29

Le tre possibilità che mi vengono in mente:

  • Esiste un alias per emacs(che hai controllato)
  • Esiste una funzione per emacs
  • Il nuovo emacsbinario non è nella tabella hash PATH della shell.

Puoi verificare se hai una funzione emacs:

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

E rimuovilo:

unset -f emacs

La shell ha anche una tabella hash PATH che contiene un riferimento a ciascun file binario nel PATH. Se aggiungi un nuovo binario con lo stesso nome di un altro esistente nel tuo PERCORSO, la shell deve essere informata aggiornando la tabella hash:

hash -r

Spiegazione aggiuntiva:

which non conosce le funzioni, in quanto non è un built-in 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

Il nuovo comportamento di hashtable binario è dimostrato da questo script.

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

Anche se non l'ho chiamato, which catrestituirei sempre il primo catnel mio PERCORSO, perché non usa l'hashtable della shell.


1
Mentre ci sono buone informazioni qui, manca il typecomando.
Giordania,

Grazie, ho avuto lo stesso problema con una versione appena compilata di sqlite3 che mi ha fatto impazzire (che in realtà ha restituito il percorso giusto, ma la shell non ha chiamato il giusto sqlite3 cli). hash -rha risolto il mio problema.
mpm,

12

Sì, non usare quali :

  • Su alcuni sistemi, è un comando esterno implementato come uno script csh, che può leggere una configurazione che cambia il PATH.
  • C'è un incorporato per questo. Due, anche: typee command. Il modo POSIX:

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

    In bash, puoi anche usare type -p emacsper vedere solo il percorso di un comando esterno.

Tuttavia, qui, in whichrealtà è giusto. Bash mantiene le informazioni sulla posizione di un comando in memoria, in modo che possa eseguire il comando più velocemente la volta successiva. Hai installato un nuovo emacseseguibile sul tuo PATH, ma bash ha ancora la vecchia posizione nella sua cache. Esegui hash emacsper cercare di emacsnuovo o hash -rper svuotare la cache.


1

Hai effettuato il logout e l'accesso per far .bashrcrileggere il tuo file di accesso aggiornato ? In caso contrario, l'ambiente della sessione corrente non è stato aggiornato.


Se così fosse, `which emacs` --versionsarebbe d'accordo emacs --version, perché whicheredita il suo PERCORSO dalla shell corrente.
MR

@mrb: punto ben ripreso.
JRFerguson,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.