Wie sucht Unix nach ausführbaren Dateien?

46

Wie sucht Unix nach einer ausgeführten Datei? Wenn sich in PATH mehrere ausführbare Dateien mit demselben Namen befinden, welche wird bevorzugt? Ist das aktuelle Verzeichnis in der Suche enthalten, wenn eine Datei ausgeführt wird?

Angenommen, executable.shim aktuellen Verzeichnis befindet sich eine Datei mit dem Namen . Würde das funktionieren, wenn es ausgeführt wird $ executedund .nicht Teil des ist PATH?

Leonid
quelle
Erwähnung which <executable>Befehl wird in diesem Thread nützlich sein.
Buchhalter م

Antworten:

44

$ PATH wird von Anfang bis Ende durchsucht, wobei die erste übereinstimmende ausführbare Datei ausgeführt wird. Daher haben Verzeichnisse am Anfang von $ PATH Vorrang vor den später hinzukommenden Verzeichnissen. Ausführbare Dateien im aktuellen Verzeichnis (.) Werden nur ausgeführt, wenn. ist in $ PATH (was normalerweise nicht der Fall ist ). Es gibt keine implizite Einbeziehung des aktuellen Verzeichnisses in den Suchpfad.

Kegeltöter
quelle
Es ist seltsam, dass mein $ PATH nichts enthält ., aber es scheint, als würde zuerst nach dem aktuellen Verzeichnis gesucht, bevor in $ PATH selbst definierte Verzeichnisse überprüft werden.
Eric Wang
19

Bei Dateien im aktuellen Verzeichnis müssen Sie diesen voranstellen ./, damit der Befehl zu wird ./executable.sh. Sie sollten unter keinen Umständen .in Ihrem PFAD sein, da dies unter anderem ein Sicherheitsrisiko darstellt.

Verzeichnisse, die im PATH an erster Stelle stehen und zuerst durchsucht werden.

Die Gesamtreihenfolge für die Suche ist wie folgt, wenn ich mich richtig erinnere:

  • Aliase

  • exportierte Funktionen

  • eingebaute Shell-Befehle

  • Skripte und Binärdateien in Ihrem PATH

John T
quelle
7
Ich füge den Hash hinzu - erinnere mich, dass bash (und vielleicht auch andere Shells) einen Hash kürzlich verwendeter Befehle enthält, um das Auffinden zu vereinfachen. Manchmal müssen Sie den Cache leeren (mithilfe von hash -r), wenn Sie den Pfad oder die Programmposition ändern.
Rich Homolka
3
+1 für die Reihenfolge der Suche. Wäre nett, wenn Sie sich an die Informationsquelle erinnern könnten :)
twan163
8

Obwohl dies von einigen anderen gut beantwortet wurde, möchte ich einige Gedanken hinzufügen:

1) PATH wird nur abgefragt, wenn die aufgerufene ausführbare Datei keine Pfadelemente enthält. einKommando würde in $ PATH nachgeschlagen, ./somecommandoder /usr/bin/somecommand, oder ../../bin/somecommandnur Gebrauch Verzeichnis Regeln, nicht PATH

Wenn es in PATH mehrere ausführbare Dateien mit demselben Namen gibt, welche wird bevorzugt?

Es stoppt beim ersten gefundenen und liest $ PATH von links nach rechts.

Ist das aktuelle Verzeichnis in der Suche enthalten, wenn die Datei ausgeführt wird?

Befindet sich das aktuelle Verzeichnis in PATH, wird es durchsucht. Denken Sie daran, dass ein leeres Verzeichnis in PATH das aktuelle Verzeichnis enthält. Beispiel: PATH =: / usr / bin (leer) PATH = / usr / bin: (leer am Ende) und PATH = / usr / bin :: / bin (leer in der Mitte) enthalten effektiv das aktuelle Arbeitsverzeichnis.

Angenommen, in einem aktuellen Verzeichnis befindet sich eine Datei mit dem Namen executable.sh. Würde das funktionieren, wenn es ausgeführt wird und $ ausgeführt. gehört nicht zum PATH?

Es würde es nie finden, wenn es PATH durchsucht. Wenn sich das aktuelle Verzeichnis nicht in PATH befindet, wird es bei einer PATH-Suche nicht gefunden.

Das heißt (und es tut mir leid, um Verwirrung zu stiften), wenn es einen Alias ​​oder eine Funktion gibt, die den Befehl ausführt, wird er ausgeführt. Oder wenn Ihre Shell einen Location-Cache hatte und sich die ausführbare Datei im Cache befand, wird sie möglicherweise gefunden. Es wird es also niemals in PATH finden, aber es kann auf andere Weise ausgeführt werden.

Reiche Homolka
quelle
Vielen Dank für den cacheHinweis, es macht mich fast verrückt, dass die alte ausführbare Datei /usr/bin/immer noch aufgerufen wird, nicht die neue. /usr/local/binSie befindet sich jedoch links in der $PATHListe, bis ich mich abgemeldet und wieder angemeldet habe.
Buchhalter م
1
@theaccountant in Bash können Sie "Hash-R" tun, um den Shell-Cache zu löschen
Rich Homolka
4

Um zu sehen, was Ihr Pfad gerade ist echo $PATH, geben Sie oder ein printenv PATH.

Dann kennen Sie die Reihenfolge der Suche. Wenn Sie mehrere Dateien mit demselben Namen haben, führen Sie einfach die ____ aus, um sie anzuzeigen.

Ex.

System #> welches grep

/ usr / bin / grep

Eine coole Möglichkeit, Dateien zu finden, die wie Ihr Ziel funktionieren, ist die Verwendung von apropos:

apropos grep

bzgrep (1) - Durchsucht möglicherweise bzip2-komprimierte Dateien nach einem regulären Ausdruck

egrep (1) - druckt Zeilen, die mit einem Muster übereinstimmen

fgrep (1) - druckt Zeilen, die mit einem Muster übereinstimmen

grep (1) - druckt Zeilen, die einem Muster entsprechen

und so weiter...

mbb
quelle
2
Oh ja - ich habe die whereis - Funktion vergessen , um ALLE Instanzen einer Datei zu finden:> whereis grep
mbb
grep: / bin / grep / usr / bin / grep /usr/share/man/man1/grep.1.gz
mbb
whereisverwendet eine fest codierte Liste von Standorten, nicht $PATH.
Grawity
@grawity Könnten Sie das näher erläutern?
WinEunuuchs2Unix
-2

@ coneslayer- Die Standardreihenfolge für die Suche nach ausführbaren Dateien ist der aktuelle Pfad, die eingebauten Befehle und dann $ PATH. Wenn also eine Funktion mit dem Namen executable bereits in der pwd vorhanden ist, wird diese ausgeführt. Wenn dies nicht der Fall ist, sucht die Rangfolge nach eingebauten Befehlen der Shell und dann nach $ PATH

proc
quelle
Wenn Sie über die Thompson-Muschel, die Mashey-Muschel oder einen anderen versteinerten Überrest vor 40 Jahren gesprochen haben, haben Sie vielleicht Recht. Aber keine aktuelle Unix-Mainstream-Shell durchsucht das aktuelle Verzeichnis automatisch.
Scott
@Scott Also ist der Standardsuchpfad für einen Befehl erst eingebaut und dann $ PATH und durchsucht die CWD nur, wenn ich ./? Habe ich recht?
proc
Nun, Aliase, Funktionen und integrierte Funktionen. Wenn Sie dann mit dem Befehl (einschließlich ./) einen Pfad angeben , wird nur dieses Verzeichnis durchsucht. Andernfalls wird gesucht $PATH.
Scott