Pourquoi est-ce que 'type qui' dit que 'qui est haché'?

23

Dans le cas des shell-intégrées (par exemple type lui-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

Dans le 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 which dit-il que which is hashed ? Quelle est la signification de which étant haché et que signifie-t-il réellement?

    
posée Aditya 11.04.2014 - 20:50
la source

1 réponse

30

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 which est haché, cela signifie qu'il a déjà effectué la recherche PATH et a trouvé which et a enregistré sa position dans le hachage.

man bash l'explique comme suit:

  

Bash utilise une table de hachage pour mémoriser les chemins d'accès complets de          fichiers exécutables (voir hash 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 du shell, il y a un cas où cela pose problème. Si vous mettez à jour votre système et que, par conséquent, certains fichiers exécutables sont déplacés vers un nouvel emplacement, le shell peut être perturbé. La solution consiste à 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 sont-ils absents du hachage?

Un exécutable n'est pas placé dans le hachage tant que vous ne l'avez pas exécuté au moins une fois. Observez:

$ 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 son exécution.

Comment examiner ce que contient le hash de bash

Le contenu du hachage 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 hachage est vide. Les commandes sont ajoutées une par une au fur et à mesure de leur utilisation. 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" )'
    
réponse donnée John1024 11.04.2014 - 20:57
la source

Lire d'autres questions sur les étiquettes