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.
hashhits command
4 /usr/bin/git
2 /usr/bin/ls
1 /usr/bin/python3Die 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
-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.
hash -r
hashhash: hash table emptyDer 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:
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:
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
- Bash Reference Manual: Bash Builtins —
hashin der offiziellen Bash-Doku - POSIX hash(1p) — POSIX-Spezifikation
- Bash Reference Manual: The Set Builtin —
set +hund andere Shell-Optionen
Verwandte Artikel
- Linux which — PATH-Lookup ohne Cache
- Linux type — Sieht den Hash-Cache mit
- Linux command — POSIX-Standard zur Befehlsauflösung
- Linux Shell — Bash-Builtins und Auflösungsreihenfolge
- Umgebung & Variablen —
$PATHund andere Variablen