Warum ist . standardmäßig im Pfad?

565
alsadk

Viele sagen aus Sicherheitsgründen, dass sich das aktuelle Verzeichnis nicht in der $PATHVariablen befindet und Linux im aktuellen Verzeichnis nicht nachschaut, ob ein bestimmter Befehl in diesem Verzeichnis verfügbar ist. aber ich tat es cd /usr/bindann lsund es hat gut funktioniert; auch ich habe echo $PATHund die Ausgabe enthält /usr/bin.

Sie sollten beachten, dass sich das aktuelle Verzeichnis aus Sicherheitsgründen nicht in der $PATHVariablen befindet und Linux im aktuellen Verzeichnis nicht nach einem bestimmten Befehl aus diesem Verzeichnis sucht.

Red Hat® RHCSATM / RHCE® 7 Cert Guide von Sander van Vugt

Warum kann ich rennen, lswenn ich dabei bin /usr/bin?

0

2 Antworten auf die Frage

4
Glorfindel

linux sucht im aktuellen Verzeichnis nicht nach, ob ein bestimmter Befehl in diesem Verzeichnis verfügbar ist

Das stimmt, aber es sieht in allen Verzeichnissen aus, die in erwähnt werden $PATH, auch wenn Sie sich gerade in einem solchen Verzeichnis befinden.

Um es .anders auszudrücken, wenn es nicht in Ihrem steht $PATH, ist es egal, wo Sie sich befinden. Es durchsucht immer dieselben Verzeichnisse, um zu sehen, ob dort ein bestimmter Befehl verfügbar ist.

Aber so wie ich verstanden habe, sollte das aktuelle Verzeichnis nicht in $ PATH stehen. Warum ist es noch in $ PATH, nachdem ich in das Verzeichnis / usr / bin gewechselt bin? "Sie sollten beachten, dass sich das aktuelle Verzeichnis aus Sicherheitsgründen nicht in der Variablen $ PATH befindet und Linux im aktuellen Verzeichnis nicht nach einem bestimmten Befehl aus diesem Verzeichnis sucht." Red Hat® RHCSATM / RHCE® 7 Cert Guide von Sander van Vugt alsadk vor 5 Jahren 0
Das bedeutet nur, dass * normalerweise * nicht im aktuellen Verzeichnis (im Gegensatz zu Windows) gesucht wird. Glorfindel vor 5 Jahren 1
Also sucht Linux nicht im aktuellen Verzeichnis, es sei denn, es ist $ PATH, oder? alsadk vor 5 Jahren 0
Ja, und wenn `.` in` $ PATH` steht, wird * immer * im aktuellen Verzeichnis gesucht. Glorfindel vor 5 Jahren 2
0
Kamil Maciorowski

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 $PATHsieht so aus /usr/local/bin:/usr/bin:/bin:;
  • du bist in der Bash;
  • du tippst lsund 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 lsObjekt aus der Liste unten aus. Es ist diese Liste, die auf Ihren Fall zugeschnitten ist.

  1. ls Funktion.
  2. lsbuiltin (ist normalerweise lsnicht in Bash eingebaut; da Bash jedoch neue eingebaute Befehle dynamisch laden kann, können Sie lsein eingebautes Programm erstellen).
  3. lsausführbare Datei, deren vollständiger Pfadname in einer Hash-Tabelle gespeichert ist (dies geschieht, wenn die lsausführbare Datei irgendwann in der Vergangenheit gemäß dem nächsten Punkt gefunden wurde und immer noch daran erinnert wird).
  4. lsausführbar von $PATH. In Ihrem Fall lautet die Reihenfolge:
    1. /usr/local/bin/ls
    2. /usr/bin/ls
    3. /bin/ls

Beachten Sie, dass es keine ./lsProzedur 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 ./lsin der obigen Liste kein Hardcode enthalten ist. Es würde auf der Liste erscheinen, wenn Sie aber $PATHenthalten.

Aus Sicherheitsgründen befindet sich das aktuelle Verzeichnis nicht in der $PATHVariablen

Ich werde diese Gründe später in der Antwort erläutern. Noch können Sie hinzufügen, .um Ihre $PATHauf eigene Faust. In diesem Fall ./lserscheint in der Liste der Eintrag 4.x. Vergleichen Sie es mit Windows, das lsim aktuellen Arbeitsverzeichnis suchen würde, unabhängig davon, ob es sich in diesem Verzeichnis befindet $PATHoder nicht. Wenn Linux das gleiche tat, dann würde es immer sein ./lsEintrag irgendwo über dem Punkt 3 unserer Liste fest einprogrammiert.

Wenn Ihr aktuelles Arbeitsverzeichnis ist /usr/binund in der Liste angegeben werden lssoll /usr/bin/ls, dann ist es technisch die gleiche ausführbare Datei als ./lsaber

  • Die Shell verwendet niemals den wörtlichen ./lsPfad, die Prozedur ergibt sich /usr/bin/ls;
  • die Tatsache, in der Sie sich befinden, /usr/binbedeutet nichts ;
  • die Tatsache /usr/binist in $PATHbedeutet eine Menge .

Aber wenn Sie .als erster Eintrag in Ihrem $PATHdann hätten

  • Die Shell würde den wörtlichen ./lsPfad verwenden.
  • Die Tatsache, dass Sie sich darin befinden, /usr/binwürde viel bedeuten .
  • Die Tatsache /usr/binist in, $PATHwü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/directoryist in meinem $PATHund ich bin im /some/particular/directoryMoment"

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 $PATHin 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/lsvon einem anderen Benutzer aufgerufen wird und Sie eingeben ls(um das normale /bin/lsProgramm auszuführen ), wird Ihre Shell stattdessen ./lsdas 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/lsGrund zu verbieten, nur weil Sie hier sind /usr/bin. Wenn lses 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 lsfunktioniert 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/bintrotzdem aus, weil es in Ihrem ist $PATH.