Warum sagt "type which" "which hashed"?

31

Bei Shell-Builtins (zB typeselbst):

$ type type
type is a shell builtin

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

Bei Befehlen (normalerweise) (zB python):

$ type python
python is /usr/bin/python

$ which python
/usr/bin/python

Im Falle von which(welches ein Befehl ist, der sich bei befindet /usr/bin/which)

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

Warum type whichsagt das which is hashed? Was whichbedeutet es, gehackt zu werden und was bedeutet es tatsächlich?

Aditya
quelle

Antworten:

40

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 whichangibt, dass es sich um einen Hash handelt, bedeutet dies, dass sie die PATH-Suche bereits durchgeführt whichund 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 bashArray 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" )'
John1024
quelle
+1, ziemlich gute Erklärung. Aber warum für whichund nicht für python?
Jobin
@Jobin Siehe aktualisierte Antwort.
John1024
2
Es sieht so aus, als ob der Hash nur so lange besteht, bis wir die Shell nicht verlassen. Sobald wir das Terminal neu starten, heißt es nicht, dass der Befehl gehasht ist.
Aditya
1
@Aditya Ja. Ich habe der Antwort einen Abschnitt hinzugefügt.
John1024
hash -lwäre einfacher zu bedienen alsdeclare -p BASH_CMDS
phuclv