Pourquoi "type qui" dit ce "qui est haché"?

31

En cas d'interprétations de shell (par exemple, typeelle-même):

$ type type
type is a shell builtin

$ which type
<Doesn't return anything since it's a shell builtin, silently exits>

En cas de commandes (normalement) (par exemple python):

$ type python
python is /usr/bin/python

$ which python
/usr/bin/python

En cas de which(qui est une commande située à /usr/bin/which)

$ type which
which is hashed (/usr/bin/which)
$ which which
/usr/bin/which

Pourquoi type whichdit ça which is hashed? Quelle est la signification d' whichêtre haché et que signifie-t-il réellement?

Aditya
la source

Réponses:

41

Vous avez probablement un long ensemble PATH et, pour trouver un exécutable, le shell doit rechercher le chemin. Pour éviter ce processus fastidieux à chaque fois que vous souhaitez exécuter un programme, le shell peut conserver une liste des programmes qu'il a déjà trouvés. Cette liste s'appelle un "hash". Lorsque le shell dit que le hachage whichest en cours, cela signifie qu'il a déjà effectué la recherche PATH et trouvé whichet enregistré son emplacement dans le hachage.

man bash l'explique comme suit:

Bash utilise une table de hachage pour mémoriser le chemin d'accès complet des fichiers exécutables (voir hachage sous SHELL BUILTIN COMMANDS ci-dessous). Une recherche complète des répertoires dans PATH est effectuée uniquement si la commande est introuvable dans la table de hachage.

Bien que le hachage accélère normalement les opérations de shell, il existe un cas où il pose des problèmes. Si vous mettez à jour votre système et que, par conséquent, certains exécutables sont déplacés vers un nouvel emplacement, le shell peut devenir confus. La solution consiste à exécuter hash -rle shell qui oublie tous les emplacements hachés et effectue une recherche à partir de PATH.

Pourquoi certains exécutables sont-ils absents du hachage?

Un exécutable n'est placé dans le hachage qu'après avoir exécuté au moins une fois. Observer:

$ type python
python is /usr/bin/python
$ python --version
Python 2.7.3
$ type python
python is hashed (/usr/bin/python)

python est haché seulement après avoir été exécuté.

Comment examiner ce qu'il y a dans le hash de bash

Le contenu du hachage est disponible dans le bashtableau BASH_CMDS. Vous pouvez voir ce qu'il y a dedans avec la commande declare -p BASH_CMDS. Lorsqu'un nouveau shell ou sous-shell est ouvert, le hachage est vide. Les commandes sont ajoutées une par une au fur et à mesure de leur utilisation. A partir d'un shell récemment 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" )'
John1024
la source
+1, très bonne explication. Mais pourquoi pour whichet pas pour python?
jobin
@Jobin Voir la réponse mise à jour.
John1024
2
On dirait que le hash ne persiste que jusqu'au moment où nous ne sortons pas de la coque. Une fois que nous redémarrons le terminal, cela ne dit pas que la commande est hachée.
Aditya
1
@Aditya Oui. J'ai ajouté une section à ce sujet à la réponse.
John1024
hash -lserait plus facile à utiliser quedeclare -p BASH_CMDS
phuclv