web-dev-qa-db-fra.com

Comment effacer le cache de Bash des chemins d'accès aux exécutables?

Lorsque j'exécute un programme sans spécifier le chemin d'accès complet à l'exécutable, et Bash doit rechercher les répertoires dans $PATH pour trouver le binaire, il semble que Bash se souvienne du chemin dans une sorte de cache. Par exemple, j'ai installé une version de Subversion de la source vers /usr/local, puis tapé svnsync help à l'invite Bash. Bash a localisé le binaire /usr/local/bin/svnsync pour "svnsync" et l'a exécuté. Puis quand j'ai supprimé l'installation de Subversion dans /usr/local et relancé svnsync help, Bash répond:

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

Mais, lorsque je démarre une nouvelle instance de Bash, il trouve et exécute /usr/bin/svnsync.

Comment effacer le cache des chemins d'accès aux exécutables?

276
Daniel Trebbien

bash met en cache le chemin complet d'une commande. Vous pouvez vérifier que la commande que vous essayez d'exécuter est hachée avec la commande type:

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

Pour vider l'intégralité du cache:

$ hash -r

Ou juste une entrée:

$ hash -d svnsync

Pour plus d'informations, consultez help hash et man bash.

349
Tobu

Pour effacer une seule entrée, vous avez besoin d'un indicateur différent:

hash -d svnsync

Le -r L'indicateur ne prend pas de paramètre et supprimera toujours tout le cache.
(Au moins dans bash 3.2.39 sur Debian Lenny)

27
Aryeh Leib Taurog

Il existe des solutions non mentionnées ici.

  1. Vous pouvez désactiver le hachage avec set +h ou set +o hashall

    help set dit:

    -h - N'oubliez pas l'emplacement des commandes lorsqu'elles sont recherchées pour exécution. C'est activé par défault.

    hashall - Identique à -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. Vous pouvez vérifier qu'une commande trouvée dans la table de hachage existe avant d'essayer de l'exécuter avec shopt -s checkhash

    help shopt dit:

    checkhash - S'il est défini, bash vérifie qu'une commande trouvée dans la table de hachage existe avant d'essayer de l'exécuter. Si une commande hachée n'existe plus, une recherche de chemin normale est effectuée.

    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. Vous pouvez lier NAME avec PATH avec hash -p PATH NAME ou 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. La magie: PATH="$PATH" exécute hash -r

    De variables.c :

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

    Essayer:

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

Comme l'utilisateur johntex l'a noté dans un commentaire à réponse par l'utilisateur Tob , l'action pratique la plus simple dans Bash est de ressasser juste votre programme:

hash svnsync

C'est tout.

5
Acumenus