Sie haben wahrscheinlich einen langen PATH-Satz und um eine ausführbare Datei zu finden, muss die Shell den Pfad durchsuchen. Um diesen zeitaufwändigen Vorgang jedes Mal zu vermeiden, wenn Sie ein Programm ausführen möchten, speichert die Shell möglicherweise eine Liste der Programme, die sie bereits gefunden hat. Diese Liste wird als "Hash" bezeichnet. Wenn die Shell which
angibt, dass es sich um einen Hash handelt, bedeutet dies, dass sie die PATH-Suche bereits durchgeführt which
und ihre Position im Hash gefunden und gespeichert hat.
man bash
erklärt es wie folgt:
Bash verwendet eine Hash-Tabelle, um sich die vollständigen Pfadnamen der ausführbaren Dateien zu merken (siehe Hash unter SHELL-BUILTIN-BEFEHLE unten). Eine vollständige Suche in den Verzeichnissen in PATH wird nur durchgeführt, wenn der Befehl nicht in der Hash-Tabelle gefunden wird.
Während der Hash normalerweise die Shell-Operationen beschleunigt, gibt es einen Fall, in dem er Probleme verursacht. Wenn Sie Ihr System aktualisieren und infolgedessen einige ausführbare Dateien an einen neuen Speicherort verschoben werden, kann die Shell verwirrt werden. Die Lösung besteht darin, auszuführen hash -r
, wodurch die Shell alle Hash-Positionen vergisst und den PATH von Grund auf durchsucht.
Warum fehlen einige ausführbare Dateien im Hash?
Eine ausführbare Datei wird erst im Hash abgelegt, nachdem Sie sie mindestens einmal ausgeführt haben. Beobachten:
$ type python
python is /usr/bin/python
$ python --version
Python 2.7.3
$ type python
python is hashed (/usr/bin/python)
python
wird erst gehasht, nachdem es ausgeführt wurde.
Wie prüfe ich, was in Bashs Hash steckt?
Der Inhalt des Hashs ist im bash
Array verfügbar BASH_CMDS
. Sie können mit dem Befehl sehen, was sich darin befindet declare -p BASH_CMDS
. Wenn eine neue Shell oder Subshell geöffnet wird, ist der Hash leer. Befehle werden nacheinander hinzugefügt, sobald sie verwendet werden. Beobachten Sie aus einer neu geöffneten Muschel:
$ 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" )'
which
und nicht fürpython
?hash -l
wäre einfacher zu bedienen alsdeclare -p BASH_CMDS