So verwenden Sie den Befehl what unter Linux

Den Linux-Befehl ‚which‘ verstehen und nutzen

Der Linux-Befehl which dient dazu, die ausführbare Binärdatei zu identifizieren, die beim Aufruf eines Befehls in der Shell gestartet wird. Dies ist besonders nützlich, wenn mehrere Versionen desselben Programms auf Ihrem System existieren, da Sie so ermitteln können, welche Version von der Shell verwendet wird.

Binärdateien und ihre Pfade im Detail

Wenn Sie versuchen, ein Programm oder einen Befehl über das Terminal auszuführen, muss die Shell – in den meisten modernen Linux-Distributionen ist das die Bash – diesen Befehl auffinden und starten. Einige Befehle, wie beispielsweise cd, history und pwd, sind direkt in die Shell integriert, sodass die Bash nicht lange nach diesen suchen muss.

Wie aber findet die Bash andere Befehle, Programme und externe Binärdateien? Die Antwort liegt im Pfad, einer Sammlung von Verzeichnispfaden. Die Bash durchsucht diese Verzeichnisse nacheinander nach einer ausführbaren Datei, die dem eingegebenen Befehl oder Programmnamen entspricht. Sobald sie eine passende Datei findet, wird diese ausgeführt und die Suche beendet.

Mithilfe des Befehls echo $PATH können Sie sich die Umgebungsvariable $PATH anzeigen lassen und die darin enthaltenen Verzeichnisse einsehen. Geben Sie dazu einfach Folgendes im Terminal ein und drücken Sie Enter:

echo $PATH

Die Ausgabe listet die einzelnen Pfade, durch Doppelpunkte (:) voneinander getrennt, auf. Auf einem Beispielsystem könnte die Bash beispielsweise in dieser Reihenfolge folgende Verzeichnisse durchsuchen:

/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin

Die Existenz mehrerer Ordner mit den Namen /sbin und /bin kann gelegentlich zu Verwirrung führen.

Beispiel: Konflikte durch mehrere Versionen

Nehmen wir an, wir haben eine aktualisierte Version eines Programms namens htg. Diese liegt aktuell im aktuellen Arbeitsverzeichnis und lässt sich mit ./htg ausführen.

Dieses Programm gibt lediglich seine Versionsnummer aus und wird beendet. Die neue Version hat die Versionsnummer 1.2.138.

Um ein Programm im aktuellen Arbeitsverzeichnis auszuführen, muss ./ vor dem Namen stehen, damit die Bash weiß, wo sie es finden kann.

Um dieses Programm von jedem beliebigen Verzeichnis aus aufrufen zu können, verschieben wir die ausführbare Datei nach /usr/bin, damit die Bash es im Pfad findet und ausführt.

Danach ist es nicht mehr nötig, sich im gleichen Verzeichnis aufzuhalten oder ./ vor dem Programmnamen zu verwenden, wie im nächsten Schritt gezeigt:

sudo mv htg /usr/bin

Wenn wir nun versuchen, das Programm einfach mit htg auszuführen:

htg

… stellen wir fest, dass zwar etwas ausgeführt wird, aber nicht unser neues, aktualisiertes Programm. Stattdessen startet eine ältere Version mit der Nummer 1.2.105.

Der Befehl ‚which‘ zur Fehleranalyse

Genau für solche Fälle, wie oben beschrieben, wurde der Befehl which entwickelt. (Weitere Details)

In diesem Beispiel verwenden wir which, um herauszufinden, welche Version von htg verwendet wird, indem wir den Programmnamen als Parameter übergeben:

which htg

Die Ausgabe zeigt, dass eine Version von htg im Verzeichnis /usr/local/bin gefunden wurde. Da dieser Pfad in der $PATH-Variable vor dem Verzeichnis steht, in das wir die aktualisierte Version verschoben haben, verwendet die Bash diese ältere Version.

Durch die Option -a (all) wird die Suche auch nach dem ersten Fund fortgesetzt. Dadurch werden alle Treffer angezeigt:

which -a htg

Es wird nun die Liste aller Übereinstimmungen in den Verzeichnissen des Pfades ausgegeben.

Dies ist die Ursache des Problems: Eine ältere Version des Programms existiert in einem Verzeichnis, das ebenfalls im Suchpfad liegt und vor dem Verzeichnis durchsucht wird, in dem wir die neue Version abgelegt haben.

Zur Veranschaulichung können wir die einzelnen Versionen explizit ausführen:

/usr/local/bin/htg
/usr/bin/htg

Damit ist das Problem erklärt und die Lösung einfach. Wir haben die Wahl: Entweder wir löschen die alte Version aus dem Verzeichnis /usr/local/bin oder wir verschieben die neuere Version aus /usr/bin nach /usr/local/bin.

‚which‘ liefert nicht immer eindeutige Ergebnisse

Zwei Ergebnisse von which bedeuten nicht zwingend, dass zwei Binärdateien existieren.

Betrachten wir ein Beispiel, bei dem wir which mit der Option -a verwenden, um nach Versionen des Programms less zu suchen:

which -a less

which meldet zwei Orte, die eine Version von less beinhalten, aber stimmt das wirklich? Es wäre ungewöhnlich, zwei verschiedene Versionen von less auf einem Linux-System zu haben. Nehmen wir also die Ausgabe von which nicht sofort als bare Münze und gehen wir dem genauer nach.

Mit ls -lh können wir uns genauere Informationen anzeigen lassen:

ls -lh /usr/bin/less

Die Dateigröße beträgt lediglich 9 Bytes! Das kann keine vollständige Version von less sein.

Das erste Zeichen in der Ausgabe ist ein „l“. Eine normale Datei hätte stattdessen einen Bindestrich (-). „l“ ist das Symbol für einen symbolischen Link. Sollte Ihnen dieses Detail entgangen sein, dann weist das -> auf einen symbolischen Link hin, eine Art Verknüpfung. Dieser Link verweist auf die tatsächliche Kopie von less im Verzeichnis /bin.

Versuchen wir es mit der Version von less unter /bin:

ls -lh /bin/less

Dieser Eintrag ist eindeutig eine „echte“ ausführbare Datei. Das erste Zeichen ist ein Bindestrich (-), was auf eine normale Datei hindeutet, und die Dateigröße beträgt 167 KB. Es gibt also nur eine Version von less auf dem System. Es existiert aber ein symbolischer Link in einem anderen Verzeichnis, den die Bash bei der Suche ebenfalls findet.

Mehrere Befehle gleichzeitig überprüfen

Sie können mehrere Programme und Befehle gleichzeitig an which übergeben. Diese werden dann nacheinander geprüft.

Wenn Sie beispielsweise Folgendes eingeben:

which ping cat uptime date head

… wird which die Liste der übergebenen Befehle und Programme durchgehen und das Ergebnis für jeden einzelnen ausgeben.

Der Befehl ‚which‘ untersucht sich selbst

Wenn Sie neugierig sind, können Sie auch which untersuchen, indem Sie folgendes eingeben:

which which

Abgesehen von der Neugier beim Stöbern im Linux-Dateisystem ist der Befehl which vor allem dann nützlich, wenn Sie ein bestimmtes Verhalten von einem Befehl erwarten, aber ein anderes erhalten. In solchen Fällen können Sie which verwenden, um zu überprüfen, ob die von der Bash ausgeführte Version tatsächlich die gewünschte ist.