Diese andere Antwort ist gut, aber die Diskussion in Kommentaren weist darauf hin, dass eine umfassendere Erklärung nützlich sein kann.
In diesem Dokument wird beschrieben, in welcher Reihenfolge eine POSIX-kompatible Shell nach Befehlen suchen soll. Es ist sehr allgemein, nicht das einfachste, was man verstehen kann. Anstatt dieses sehr abstrakte Verfahren zu analysieren, wollen wir sehen, wie sich eine echte Hülle verhält.
Angenommen,
- Ihr
$PATH
sieht so aus /usr/local/bin:/usr/bin:/bin
:; - du bist in der Bash;
- du tippst
ls
und drückst Enter; - Es gibt keinen
ls
Alias, der den Befehl in etwas anderes als ändern würde ls
.
dann führt Bash das erste vorhandene ls
Objekt aus der Liste unten aus. Es ist diese Liste, die auf Ihren Fall zugeschnitten ist.
ls
Funktion. ls
builtin (ist normalerweise ls
nicht in Bash eingebaut; da Bash jedoch neue eingebaute Befehle dynamisch laden kann, können Sie ls
ein eingebautes Programm erstellen). ls
ausführbare Datei, deren vollständiger Pfadname in einer Hash-Tabelle gespeichert ist (dies geschieht, wenn die ls
ausführbare Datei irgendwann in der Vergangenheit gemäß dem nächsten Punkt gefunden wurde und immer noch daran erinnert wird). ls
ausführbar von $PATH
. In Ihrem Fall lautet die Reihenfolge: /usr/local/bin/ls
/usr/bin/ls
/bin/ls
Beachten Sie, dass es keine ./ls
Prozedur gibt. An keinem Punkt wird Ihr aktuelles Arbeitsverzeichnis berücksichtigt, insbesondere nicht mit Einträgen in $PATH
.
Nun diese Aussage
Linux sucht nicht im aktuellen Verzeichnis, ob ein bestimmter Befehl in diesem Verzeichnis verfügbar ist
bedeutet nur, dass ./ls
in der obigen Liste kein Hardcode enthalten ist. Es würde auf der Liste erscheinen, wenn Sie aber $PATH
enthalten.
Aus Sicherheitsgründen befindet sich das aktuelle Verzeichnis nicht in der $PATH
Variablen
Ich werde diese Gründe später in der Antwort erläutern. Noch können Sie hinzufügen, .
um Ihre $PATH
auf eigene Faust. In diesem Fall ./ls
erscheint in der Liste der Eintrag 4.x. Vergleichen Sie es mit Windows, das ls
im aktuellen Arbeitsverzeichnis suchen würde, unabhängig davon, ob es sich in diesem Verzeichnis befindet $PATH
oder nicht. Wenn Linux das gleiche tat, dann würde es immer sein ./ls
Eintrag irgendwo über dem Punkt 3 unserer Liste fest einprogrammiert.
Wenn Ihr aktuelles Arbeitsverzeichnis ist /usr/bin
und in der Liste angegeben werden ls
soll /usr/bin/ls
, dann ist es technisch die gleiche ausführbare Datei als ./ls
aber
- Die Shell verwendet niemals den wörtlichen
./ls
Pfad, die Prozedur ergibt sich /usr/bin/ls
; - die Tatsache, in der Sie sich befinden,
/usr/bin
bedeutet nichts ; - die Tatsache
/usr/bin
ist in $PATH
bedeutet eine Menge .
Aber wenn Sie .
als erster Eintrag in Ihrem $PATH
dann hätten
- Die Shell würde den wörtlichen
./ls
Pfad verwenden. - Die Tatsache, dass Sie sich darin befinden,
/usr/bin
würde viel bedeuten . - Die Tatsache
/usr/bin
ist in, $PATH
würde nichts bedeuten .
In beiden Fällen ist es die gleiche ausführbare Datei, die am Ende des Tages ausgeführt wird, aber die Shell kann auf unterschiedliche Weise darauf zugreifen.
Es ist auch erwähnenswert, dass Aussagen wie "Mein aktuelles Arbeitsverzeichnis ist in meinem $PATH
" oder "Ich bin in einem Verzeichnis, das sich in meinem Verzeichnis befindet $PATH
" nicht die ganze Geschichte erzählen. Sie könnten bedeuten:
- "
/some/particular/directory
ist in meinem $PATH
und ich bin im /some/particular/directory
Moment"
oder
- "Der wörtliche
.
Eintrag ist in meinem $PATH
".
Wie gezeigt, unterscheiden sich die beiden Fälle.
Es sieht so aus ls
, als hätten Sie erwartet, nicht gefunden zu werden, nur weil Sie zufällig in seinem Verzeichnis sind. Nun, dies wäre unbequem, während es keinerlei Sicherheitsvorteile geben würde. Der wichtigste Sicherheits Grund für die nicht mit .
in einer allgemeinen Befehlssuchsequenz als Fest Schritt und für nicht mit .
in $PATH
in erklärte diese UNIX FAQ :
Überlegen Sie, was passiert, wenn .
der erste Eintrag in der PATH
. Angenommen, Ihr aktuelles Verzeichnis ist öffentlich beschreibbar, z /tmp
. B.. Wenn nur zufällig ein Programm /tmp/ls
von einem anderen Benutzer aufgerufen wird und Sie eingeben ls
(um das normale /bin/ls
Programm auszuführen ), wird Ihre Shell stattdessen ./ls
das Programm des anderen Benutzers ausführen . Es ist unnötig zu erwähnen, dass Sie die Ergebnisse eines unbekannten Programms wie dieses überrascht.
Es gibt keinen /usr/bin/ls
Grund zu verbieten, nur weil Sie hier sind /usr/bin
. Wenn ls
es bösartig ist, haben Sie es wahrscheinlich bereits ausgeführt, während Sie in einem anderen Verzeichnis gearbeitet haben, oder Sie werden es eventuell ausführen, während Sie in einem anderen Verzeichnis arbeiten.
tl; dr
Zusammenfassend ls
funktioniert in Ihrem Beispiel, weil es das ist /usr/bin/ls
, was gefunden wird, nicht ./ls
. Die Tatsache, dass der letztere Pfad zum ersten Pfad aufgelöst wird, spielt keine Rolle, da der letztere Pfad nicht verwendet wird. Es wird nicht verwendet, weil "Linux nicht im aktuellen Verzeichnis sucht ..." (bedeutet, dass es nicht hineinschaut .
). Es sieht /usr/bin
trotzdem aus, weil es in Ihrem ist $PATH
.