it-swarm.com.de

Was ist der Zweck des Hash-Befehls?

Wenn Sie hash ausführen, wird der Pfad aller Befehle angezeigt, die seit dem letzten Zurücksetzen des Hash ausgeführt wurden (hash -r).

[[email protected] ~]# hash
hash: hash table empty

[[email protected] ~]# whoami
root

[[email protected] ~]# hash
hits    command
   1    /usr/bin/whoami

[[email protected] ~]# whoami
root

[[email protected] ~]# hash
hits    command
   2    /usr/bin/whoami

Laut den Manpages ist der Zweck von Hash:

Das Dienstprogramm/usr/bin/hash beeinflusst die Art und Weise, wie sich die aktuelle Shell-Umgebung die Speicherorte der gefundenen Dienstprogramme merkt. Abhängig von den angegebenen Argumenten werden Dienstprogrammspeicherorte zu der Liste der gespeicherten Speicherorte hinzugefügt oder der Inhalt der Liste gelöscht. Wenn keine Argumente angegeben werden, wird über den Inhalt der Liste berichtet. Die Option -r Bewirkt, dass die Shell alle gespeicherten Speicherorte vergisst.

Dienstprogramme, die als integrierte Funktionen für die Shell bereitgestellt werden, werden nicht von Hash gemeldet.

Abgesehen davon, wie oft ich einen Befehl eingegeben habe, kann ich das Dienstprogramm von hash nicht sehen.

Es wurde sogar in thegeekstuff.coms Top 15 nützliche Befehle vorgestellt

Inwiefern ist hash nützlich?

122
spuder

hash ist ein in bash integrierter Befehl. Die Hash-Tabelle ist eine Funktion von bash, die verhindert, dass jedes Mal, wenn Sie einen Befehl eingeben, $PATH Gesucht werden muss, indem die Ergebnisse im Speicher zwischengespeichert werden. Die Tabelle wird bei Ereignissen gelöscht, die die Ergebnisse offensichtlich ungültig machen (z. B. Ändern von $PATH).

Mit dem Befehl hash können Sie genau mit diesem System interagieren (aus welchem ​​Grund auch immer Sie dies für erforderlich halten).

Einige Anwendungsfälle:

  • Wie Sie gesehen haben, wird ausgedruckt, wie oft Sie welche Befehle gedrückt haben, wenn Sie es ohne Argumente eingeben. Hier erfahren Sie möglicherweise, welche Befehle Sie am häufigsten verwenden.

  • Sie können es auch verwenden, um sich ausführbare Dateien an nicht standardmäßigen Speicherorten zu merken.

Beispiel:

[[email protected] ~]# hash -p /lol-wut/whoami whoami
[[email protected] ~]# whoami
Not what you're thinking
[[email protected] ~]# which whoami
/usr/bin/whoami
[[email protected] ~]# /usr/bin/whoami
root
[[email protected] ~]#

Dies kann nützlich sein, wenn Sie nur eine einzige ausführbare Datei in einem Verzeichnis außerhalb von $PATH Haben, die Sie ausführen möchten, indem Sie einfach den Namen eingeben, anstatt alles in dieses Verzeichnis aufzunehmen (was der Effekt wäre, wenn Sie es hinzufügen würden $PATH).

Ein Alias ​​kann dies normalerweise auch tun. Da Sie jedoch das Verhalten der aktuellen Shell ändern, wird es in Programmen, die Sie starten, nicht zugeordnet. Ein Symlink zur einsamen ausführbaren Datei ist hier wahrscheinlich die bevorzugte Option. hash ist eine Möglichkeit, dies zu tun.

  • Sie können es verwenden, um sich an Dateipfade zu erinnern. Dies ist nützlich, wenn eine neue ausführbare Datei in einem früheren PATH -Verzeichnis angezeigt wird oder mv 'd an eine andere Stelle verschoben wird und Sie bash zwingen möchten, sie anstelle der letzten Stelle erneut zu suchen es erinnert sich daran, es gefunden zu haben.

Beispiel:

[[email protected] ~]# hash
hits    command
   1    /bin/ls
[[email protected] ~]# cp /bin/ls /lol-wut
[[email protected] ~]# hash
hits    command
   1    /bin/cp
   1    /bin/ls
[[email protected] ~]# hash -d ls
[[email protected] ~]# ls
default.ldif  newDIT.ldif  notes.txt  users.ldif
[[email protected] ~]# hash
hits    command
   1    /bin/cp
   1    /lol-wut/ls
[[email protected] ~]#

Der Befehl cp hat dazu geführt, dass eine neue Version der ausführbaren Datei ls früher in meinem $PATH Angezeigt wurde, aber keine Bereinigung der Hash-Tabelle ausgelöst hat. Ich habe hash -d Verwendet, um den Eintrag für ls selektiv aus der Hash-Tabelle zu löschen. Bash war dann gezwungen, $PATH Erneut durchzusehen, und als es dies tat, fand es es an der neueren Stelle (früher in $ PATH als zuvor).

Sie können dieses Verhalten "Neuen Speicherort der ausführbaren Datei aus $PATH Suchen" selektiv aufrufen:

[[email protected] ~]# hash
hits    command
   1    /bin/ls
[[email protected] ~]# hash ls
[[email protected] ~]# hash
hits    command
   0    /lol-wut/ls
[[email protected] ~]#

Meistens möchten Sie dies nur tun, wenn Sie etwas aus der Hash-Tabelle entfernen möchten und nicht zu 100% erfolgreich abmelden und dann wieder eintragen möchten, oder wenn Sie einige Änderungen beibehalten möchten, die Sie an Ihrer Shell vorgenommen haben.

Um veraltete Zuordnungen zu entfernen, können Sie auch hash -r (Oder export PATH=$PATH) Ausführen, wodurch effektiv nur die gesamte Hash-Tabelle von bash gelöscht wird.

Es gibt viele kleine Situationen wie diese. Ich weiß nicht, ob ich es als einen der "nützlichsten" Befehle bezeichnen würde, aber es gibt einige Anwendungsfälle.

100
Bratchley

Hier ist die klassische Verwendung, vereinfacht:

# 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.
40
rici

Hier ist eine nützliche Verwendung von hash:

hash php 2> /dev/null || hash -p /usr/local/foobar/php/bin/php php 2> /dev/null

Es bedeutet: Wenn PHP nicht im Pfad ist, dann verwenden Sie

/usr/local/foobar/php/bin/
18
Gilles Quenot

Ja, Bash Reference Manual sagt:

Eine vollständige Suche in den Verzeichnissen in $ PATH wird nur durchgeführt, wenn der Befehl nicht in der Hash-Tabelle gefunden wird.

Sie können das Hashing jedoch mit set +h Deaktivieren:

-h - Suchen und merken Sie sich (Hash-) Befehle, während sie zur Ausführung gesucht werden. Diese Option ist standardmäßig aktiviert.

Versuchen:

set +h
hash # prints bash: hash: hashing disabled
echo $? # prints 1

Gleiches gilt für hash -r, hash NAME Usw.

Eine "Befehlserkennung" (wie this oder that ) funktioniert nicht:

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

Sie können so etwas schreiben:

old_options="$-"
set -h
hash ls >/dev/null 2>&1 || echo "Please install ls" >&2
[[ "$old_options" =~ "h" ]] || set +h

oder (dank @mikeserv) ohne neue Variablen zuweisen oder Tests durchführen zu müssen:

set -h -- "-${-:--}" "[email protected]"
hash ls >/dev/null 2>&1 || echo "Please install ls" >&2
set +h "[email protected]"
8

Einfache Erkennung, ob ein Befehl verfügbar ist:

CMD=gzip
if hash bzip2; then
    CMD=$_
fi
6
brablc