Damit die Shell nicht bei jedem Aufruf den gesamten $PATH durchsuchen muss, merkt sie sich die Pfade gefundener Programme in einer internen Hash-Tabelle. Der Builtin hash zeigt diesen Cache, setzt ihn zurück oder löscht einzelne Einträge. Wer das nicht kennt, wundert sich nach Programm-Updates regelmäßig, warum die Shell die alte Version aufruft.

Was hash macht

Beim ersten Aufruf eines Programms durchsucht die Bash $PATH von links nach rechts. Den gefundenen Pfad legt sie in einer internen Tabelle ab — mit hash schaust du dir diese Tabelle an.

Bash Cache anzeigen
hash
Output
hits	command
   4	/usr/bin/git
   2	/usr/bin/ls
   1	/usr/bin/python3

Die Spalte hits zählt, wie oft der Befehl in der aktuellen Shell aufgerufen wurde. Der Cache lebt nur in der laufenden Shell-Session — eine neue Shell startet mit leerer Tabelle.

Optionen

Optionen
-l

Gibt den Cache in einem Format aus, das wieder als Eingabe lesbar ist (hash -p ...).

-r

Setzt den gesamten Cache zurück. Wichtig nach Software-Updates, die ein Programm an einen anderen Pfad verschieben.

-d name

Entfernt einen einzelnen Eintrag aus dem Cache.

-p pfad name

Trägt einen Pfad ohne PATH-Lookup in den Cache ein. Damit kannst du der Shell explizit vorgeben, woher sie ein Programm nimmt.

-t name

Gibt nur den gespeicherten Pfad für einen bestimmten Befehl aus.

Bash Cache zurücksetzen
hash -r
hash
Output
hash: hash table empty

Der klassische Fehlerfall

Du installierst eine neue Version eines Programms an einem anderen Pfad — zum Beispiel von /usr/bin/node nach /usr/local/bin/node. In derselben Shell rufst du node auf und es passiert: nichts. Oder die alte Version startet. Oder die Fehlermeldung lautet, das Programm gebe es nicht.

Der Grund: Bash hat den alten Pfad gecached und prüft nicht erneut. Drei Lösungen:

Bash Cache invalidieren
hash -r           # gesamten Cache zurücksetzen
hash -d node      # nur einen Eintrag entfernen
exec bash         # Shell neu starten (nuklearer Reset)

Caching deaktivieren

Wer den Cache gar nicht haben will (zum Beispiel auf langlebigen Shells, die häufig mit Programm-Updates konfrontiert sind), kann das Hashing per Shell-Option abschalten:

Bash Hashing deaktivieren
set +h           # in dieser Shell kein Hashing mehr
set -h           # wieder einschalten (Default)

In der ~/.bashrc permanent machen ist möglich, aber selten nötig — die kleine Performance-Einbusse durch fehlendes Caching ist auf modernen Systemen kaum messbar, der typische Bug nach hash -r aber wahnsinnig selten.

Stolperfallen

Befehl funktioniert nicht obwohl gerade installiert

Klassiker: apt install foo läuft erfolgreich durch, du tippst foo und Bash meldet command not found oder ruft eine alte Version auf. Schuld ist der Hash-Cache mit dem alten (leeren oder veralteten) Eintrag. hash -r oder exec bash lösen das. Bei sporadischen Tools, die du selten aufrufst, kann das jahrelang unbemerkt bleiben.

Cache ist nicht persistent

Der Hash-Cache lebt nur in der laufenden Shell-Session. Eine neue Shell startet mit leerer Tabelle und baut sie schrittweise wieder auf. Ein Reboot oder Logout tut dasselbe. Du musst dir also nicht merken, den Cache vor dem Schließen zu leeren — er verschwindet von selbst.

hashing in Skripten

In nicht-interaktiven Skripten ist Hashing standardmäßig aktiv, aber die Lebensdauer ist auf den Skript-Run beschränkt. Probleme treten in Skripten meistens dann auf, wenn das Skript ein Programm während des Laufs installiert oder verschiebt — dann hilft hash -r direkt vor dem nächsten Aufruf.

set +h für Mahlzeiten-Shells

Auf Bastlern, die im selben Terminal stundenlang Pakete installieren, deinstallieren und Pfade umbiegen, kann set +h in der ~/.bashrc Wunder wirken. Auf produktiven Maschinen ist es übertrieben — eine kurze hash -r-Disziplin reicht.

hash -p für Override

Mit hash -p /home/me/builds/git git kannst du die Shell zwingen, eine bestimmte Binary zu nutzen, ohne $PATH anzurühren. Praktisch zum Testen einer selbst gebauten Version, ohne den ganzen Pfad anzupassen — aber leicht zu vergessen, also dokumentieren oder kommentieren.

Weiterführende Ressourcen

Externe Quellen

/ Weiter

Zurück zu Dateisystem

Zur Übersicht