Vous avez probablement un PATH long et, pour trouver un exécutable, le shell doit rechercher dans les chemins. Pour éviter ce processus chronophage à chaque fois que vous voulez exécuter un programme, le shell peut conserver une liste des programmes qu'il a déjà trouvés. Cette liste est appelée un "hash." Lorsque le shell dit que which
est hashé, cela signifie qu'il a déjà effectué la recherche dans le PATH, trouvé which
et enregistré son emplacement dans le hash.
man bash
l'explique comme suit:
Bash utilise une table de hachage pour se souvenir des chemins d'accès complets des fichiers exécutables (voir hash sous COMMANDES INTÉGRÉES DU SHELL ci-dessous). Une recherche complète des répertoires dans le PATH n'est effectuée que si la commande n'est pas trouvée dans la table de hachage.
Alors que le hachage accélère normalement les opérations du shell, il y a un cas où il pose problème. Si vous mettez à jour votre système et qu'en conséquence, un exécutable déménage dans un nouvel emplacement, le shell peut se confondre. La solution est d'exécuter hash -r
ce qui fait que le shell oublie tous les emplacements hachés et recherche le PATH à partir de zéro.
Pourquoi certains exécutables manquent-ils dans le hash?
Un exécutable n'est pas placé dans le hash avant d'avoir été exécuté au moins une fois. Observez:
$ type python
python est /usr/bin/python
$ python --version
Python 2.7.3
$ type python
python est hashé (/usr/bin/python)
python
n'est hashé qu'après avoir été exécuté.
Comment examiner ce qui se trouve dans le hash de bash
Le contenu du hash est disponible dans le tableau bash
BASH_CMDS
. Vous pouvez voir ce qu'il contient avec la commande declare -p BASH_CMDS
. Lorsqu'un nouveau shell ou sous-shell est ouvert, le hash est vide. Les commandes sont ajoutées une par une au fur et à mesure qu'elles sont utilisées. À partir d'un shell nouvellement ouvert, observez:
$ declare -p BASH_CMDS
declare -A BASH_CMDS='()'
$ which which
/bin/which
$ declare -p BASH_CMDS
declare -A BASH_CMDS='([which]="/bin/which" )'
$ python --version
Python 2.7.3
$ declare -p BASH_CMDS
declare -A BASH_CMDS='([which]="/bin/which" [python]="/usr/bin/python" )'