Come posso cancellare la cache di Bash dai percorsi degli eseguibili?


256

Quando eseguo un programma senza specificare il percorso completo dell'eseguibile e Bash deve cercare nelle directory $PATHper trovare il binario, sembra che Bash ricordi il percorso in una sorta di cache. Ad esempio, ho installato una build di Subversion dall'origine a /usr/local, quindi digitata svnsync helpal prompt di Bash. Bash individuò il file binario /usr/local/bin/svnsyncper "svnsync" e lo eseguì. Quindi, quando ho eliminato l'installazione di Subversion /usr/locale rieseguito svnsync help, Bash risponde:

bash: /usr/local/bin/svnsync: No such file or directory

Ma, quando avvio una nuova istanza di Bash, trova ed esegue /usr/bin/svnsync.

Come posso cancellare la cache dei percorsi degli eseguibili?


7
il film più stupido di sempre
Romeno,

Risposte:


322

bashmemorizza nella cache l'intero percorso di un comando. È possibile verificare che il comando che si sta tentando di eseguire sia sottoposto a hash con il typecomando:

$ type svnsync
svnsync is hashed (/usr/local/bin/svnsync)

Per cancellare l'intera cache:

$ hash -r

O solo una voce:

$ hash -d svnsync

Per ulteriori informazioni, consultare help hashe man bash.


15
@Daniel Vale la pena aggiungere che, in bash, puoi usare il comando "type command " per scoprire di che tipo di comando si tratta - se il tuo comando è cancellato, "type" ti dirà. È anche utile dire se qualcosa è un shell incorporato o un alias.
lunchmeat317,

4
Come FYI, per modificare il PATH memorizzato nella cache se in esecuzione csh, il comando è rehash.
Kurtm,

Il rehashcomando sopra funziona anche per zsh.
Neil Traft,

Per una risposta più completa consultare unix.stackexchange.com/questions/86012/…
Ioannis Filippidis

4
In un comando è possibile richiamare il rehashing selettivo hash svnsync.
Ioannis Filippidis,

25

Per cancellare solo una voce è necessario un flag diverso:

hash -d svnsync

Il -rflag non accetta un parametro e eliminerà sempre l'intera cache.
(Almeno in bash 3.2.39 su Debian Lenny)


20

Ci sono soluzioni non menzionate qui.

  1. È possibile disabilitare l'hash con set +hoset +o hashall

    help set dice:

    -h - Ricorda la posizione dei comandi mentre vengono cercati per l'esecuzione. Questo è abilitato di default.

    hashall - Lo stesso di -h

    set -h # enable hashing
    shopt -u checkhash # disable command existence check
    hash -p /some/nonexisting/dir/date date # bind date with /some/nonexisting/dir/date
    date # bash: /some/nonexisting/dir/date: No such file or directory
    set +h
    date # normal date output
    
  2. È possibile verificare l'esistenza di un comando trovato nella tabella hash prima di provare a eseguirlo shopt -s checkhash

    help shopt dice:

    checkhash - Se impostato, bash verifica l'esistenza di un comando trovato nella tabella hash prima di provare a eseguirlo. Se non esiste più un comando con hash, viene eseguita una normale ricerca del percorso.

    set -h # enable hashing
    shopt -u checkhash # disable command existence check
    hash -p /some/nonexisting/dir/date date # bind date with /some/nonexisting/dir/date
    hash -t date # prints /some/nonexisting/dir/date
    date # bash: /some/nonexisting/dir/date: No such file or directory
    shopt -s checkhash # enable command existence check
    date # normal date output
    hash -t date # prints /bin/date
    
  3. Puoi associare NAME a PATH con hash -p PATH NAMEo BASH_CMDS[NAME]=PATH:

    shopt -u checkhash # disable command existence check
    hash -p /some/nonexisting/dir/date date
    date # bash: /some/nonexisting/dir/date: No such file or directory
    BASH_CMDS[date]=/bin/date
    date # normal date output
    
  4. Magia: PATH="$PATH"eseguehash -r

    Da variables.c:

    /* What to do just after the PATH variable has changed. */
    void
    sv_path (name)
        char *name;
    {
        /* hash -r */
        phash_flush ();
    }
    

    Provare:

    set -h
    hash -r
    date
    hash # prints 1 /bin/date
    PATH="$PATH"
    hash # prints hash: hash table empty
    

1
Non ho mai capito perché tutto il meccanismo extra sia fornito quando PATH = $ PATH funziona bene. Se il PATH cambia, la cache di ricerca PATH deve essere invalidata. Ha senso.
jrw32982,

Il caso d'uso non viene gestito invalidando la cache quando cambia il PERCORSO è quando cambiano le posizioni degli eseguibili. Questo può essere comune quando si utilizza la shell per aggiungere o rimuovere programmi, solo per avere nella cache l'ultimo posto in cui li ha trovati.
Adam,

Fare confusione con il comando hash table è un modo meraviglioso per confondere davvero qualcuno che sta provando a eseguire il debug di uno script bash.
Erik Aronesty,

4

Come ha notato l' utente johntex in un commento alla risposta dell'utente Tobu , l'azione pratica più semplice in Bash è quella di ripassare solo il tuo programma:

hash svnsync

È tutto.

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.