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.