Si vous exécutez hash
, il indique le chemin de toutes les commandes exécutées depuis la dernière réinitialisation du hachage (hash -r
)
[root@c04c ~]# hash
hash: hash table empty
[root@c04c ~]# whoami
root
[root@c04c ~]# hash
hits command
1 /usr/bin/whoami
[root@c04c ~]# whoami
root
[root@c04c ~]# hash
hits command
2 /usr/bin/whoami
Selon les pages de manuel, le but du hachage est:
L'utilitaire/usr/bin/hash affecte la façon dont l'environnement Shell actuel se souvient des emplacements des utilitaires trouvés. Selon les arguments spécifiés, il ajoute des emplacements d'utilitaires à sa liste d'emplacements mémorisés ou il purge le contenu de la liste. Lorsqu'aucun argument n'est spécifié, il rend compte du contenu de la liste. Le
-r
L'option fait que le shell oublie tous les emplacements mémorisés.Les utilitaires fournis en tant qu'éléments intégrés au shell ne sont pas signalés par le hachage.
A part voir combien de fois j'ai entré une commande, je ne vois pas l'utilité de hash
.
Il a même été présenté dans thegeekstuff.com's top 15 commandes utiles
En quoi hash
est-il utile?
hash
est une commande intégrée bash. La table de hachage est une fonctionnalité de bash
qui l'empêche d'avoir à rechercher $PATH
chaque fois que vous tapez une commande en mettant en cache les résultats en mémoire. Le tableau est effacé sur les événements qui invalident évidemment les résultats (tels que la modification de $PATH
)
La commande hash
est simplement la façon dont vous interagissez avec ce système (pour la raison que vous jugez nécessaire).
Quelques cas d'utilisation:
Comme vous l'avez vu, il affiche le nombre de fois que vous appuyez sur les commandes si vous le tapez sans argument. Cela pourrait vous indiquer les commandes que vous utilisez le plus souvent.
Vous pouvez également l'utiliser pour mémoriser les exécutables dans des emplacements non standard.
Exemple:
[root@policyServer ~]# hash -p /lol-wut/whoami whoami
[root@policyServer ~]# whoami
Not what you're thinking
[root@policyServer ~]# which whoami
/usr/bin/whoami
[root@policyServer ~]# /usr/bin/whoami
root
[root@policyServer ~]#
Ce qui peut être utile si vous n'avez qu'un seul exécutable dans un répertoire en dehors de $PATH
que vous souhaitez exécuter en tapant simplement le nom au lieu d'inclure tout dans ce répertoire (ce qui serait l'effet si vous l'ajoutiez à $PATH
).
Un alias peut généralement le faire également, et comme vous modifiez le comportement du shell actuel, il n'est pas mappé dans les programmes que vous démarrez. Un lien symbolique vers le seul exécutable est probablement l'option préférable ici. hash
est une façon de le faire.
PATH
antérieur ou obtient mv
'd ailleurs et que vous voulez forcer bash à sortir et à le retrouver à la place du dernier endroit il se souvient de l'avoir trouvé.Exemple:
[root@policyServer ~]# hash
hits command
1 /bin/ls
[root@policyServer ~]# cp /bin/ls /lol-wut
[root@policyServer ~]# hash
hits command
1 /bin/cp
1 /bin/ls
[root@policyServer ~]# hash -d ls
[root@policyServer ~]# ls
default.ldif newDIT.ldif notes.txt users.ldif
[root@policyServer ~]# hash
hits command
1 /bin/cp
1 /lol-wut/ls
[root@policyServer ~]#
La commande cp
a fait apparaître une nouvelle version de l'exécutable ls
plus tôt dans mon $PATH
mais n'a pas déclenché de purge de la table de hachage. J'ai utilisé hash -d
pour purger sélectivement l'entrée de ls
de la table de hachage. Bash a ensuite été contraint de regarder à travers $PATH
encore et quand il l'a fait, il l'a trouvé dans le nouvel emplacement (plus tôt dans $ PATH qu'il ne fonctionnait auparavant).
Vous pouvez invoquer de manière sélective ce "rechercher un nouvel emplacement d'exécutable à partir de $PATH
", cependant:
[root@policyServer ~]# hash
hits command
1 /bin/ls
[root@policyServer ~]# hash ls
[root@policyServer ~]# hash
hits command
0 /lol-wut/ls
[root@policyServer ~]#
Vous voudriez surtout le faire si vous vouliez quelque chose hors de la table de hachage et que vous ne pouviez pas vous déconnecter à 100% puis vous reconnecter avec succès, ou si vous vouliez conserver certaines modifications que vous avez apportées à votre shell.
Pour vous débarrasser des mappages périmés, vous pouvez également faire hash -r
(ou export PATH=$PATH
) qui purge efficacement la table de hachage entière de bash.
Il y a beaucoup de petites situations comme ça. Je ne sais pas si je l'appellerais l'une des commandes "les plus utiles" mais elle a quelques cas d'utilisation.
Voici l'utilisation classique, simplifiée:
# My PATH contains /home/rici/bin as well as the Usual Suspects:
# (the real one has lots more)
$ echo $PATH
/home/rici/bin:/usr/local/bin:/usr/bin:/bin
# I've installed a program called hello in /usr/local/bin
$ $ cat /usr/local/bin/hello
#!/bin/bash
echo Hello, world. I live at $0
# The program works.
$ hello
Hello, world. I live at /usr/local/bin/hello
# Now I want to create a better hello, just for me. I put it in
# my own bin directory, and according to my PATH, it should come first.
$ cp /usr/local/bin/hello ~/bin/hello
# So now I will try running it
$ hello
Hello, world. I live at /usr/local/bin/hello
# WTF? Oh, forgot to run hash.
# Tell bash to update where to look for hello
$ hash hello
$ hello
Hello, world. I live at /home/rici/bin/hello
# Ah, all is well.
Voici une utilisation utile de hash
:
hash php 2> /dev/null || hash -p /usr/local/foobar/php/bin/php php 2> /dev/null
Cela signifie: si php n'est pas dans le CHEMIN, alors utilisez
/usr/local/foobar/php/bin/
Oui, Bash Reference Manual dit:
Une recherche complète des répertoires dans $ PATH n'est effectuée que si la commande n'est pas trouvée dans la table de hachage.
Mais vous pouvez désactiver le hachage avec set +h
:
-h - Recherchez et mémorisez les commandes (hachage) lors de leur recherche pour exécution. Cette option est activée par défaut.
Essayer:
set +h
hash # prints bash: hash: hashing disabled
echo $? # prints 1
Il en va de même pour hash -r
, hash NAME
etc
Une "détection de commande" (comme this ou that ) ne fonctionne pas:
set -h
hash ls >/dev/null 2>&1 || echo "Please install ls" >&2 # prints nothing
set +h
hash ls >/dev/null 2>&1 || echo "Please install ls" >&2 # prints Please install ls
Vous pouvez écrire quelque chose comme ceci:
old_options="$-"
set -h
hash ls >/dev/null 2>&1 || echo "Please install ls" >&2
[[ "$old_options" =~ "h" ]] || set +h
ou (grâce à @mikeserv) sans devoir assigner de nouvelles variables ni faire de tests:
set -h -- "-${-:--}" "$@"
hash ls >/dev/null 2>&1 || echo "Please install ls" >&2
set +h "$@"
Détection facile si une commande est disponible:
CMD=gzip
if hash bzip2; then
CMD=$_
fi