Warum verwenden wir ./filename, um eine Datei unter Linux auszuführen?

Warum nicht Geben Sie es einfach wie andere Befehle ein gcc, ls usw. …

Kommentare

  • Würde nicht ‚ die erste Zeile besser geschrieben werden als “ Warum verwenden wir ./command_name, um einen Befehl unter Linux auszuführen? “
  • user15760, Nein, weil wir Fragen gerne haben In Suchmaschinen auffindbar und nicht alle, die diese Frage haben, sind natürlich geborene ‚ Nixster (:

Antwort

Unter Linux, UNIX und verwandten Betriebssystemen bezeichnet . das aktuelle Verzeichnis. Da Sie eine Datei in Ihrem aktuellen Verzeichnis und diesem Verzeichnis ausführen möchten Befindet sich nicht in Ihrem $PATH, benötigen Sie das Bit ./, um der Shell mitzuteilen, wo Die ausführbare Datei ist. ./foo bedeutet also, dass die ausführbare Datei mit dem Namen foo in diesem Verzeichnis ausgeführt wird.

Sie können type oder which , um den vollständigen Pfad aller Befehle zu erhalten, die in Ihrem $PATH gefunden wurden.

Kommentare

  • Es ist sehr üblich, Programme im aktuellen Verzeichnis auszuführen. Warum wird ‚ die Shell-Suche dort nicht auch durchgeführt? Es sucht zuerst in., Dann in $ PATH.
  • Es gibt auch alias es, die im Weg stehen können, nicht nur .
  • @Michael Sicherheit und Vernunft: Wenn zuerst in . gesucht wird, handelt es sich um ein Sicherheitsproblem, das Sie oder eine andere Person ersetzen könnten ls zum Beispiel (ein einfacher Virus / Trojen: Erstellen Sie eine Zip-Datei mit einer ausführbaren Datei namens ls, während jemand durchsucht, sie führen diese ausführbare Datei aus, die…). Wenn es zuletzt in . gesucht wurde, können Sie lange verrückt werden, ohne zu wissen, warum Ihr Programm nicht funktioniert (z. B. erstellen Sie ein Programm namens test, anstatt Ihr ausgeführtes Programm auszuführen das Systemtestprogramm (das keine Ausgabe erzeugt).
  • @jcubic dass ‚ eine schlechte Idee ist. Siehe den Kommentar oben. In der Vergangenheit hat DOS im aktuellen Verzeichnis gesucht und dieses Verhalten wurde auf Windows cmd übertragen, was viele Sicherheitsprobleme mit sich bringt. MS hat das in PowerShell behoben und jetzt müssen Sie. \ Verwenden, um das Programm im aktuellen Verzeichnis auszuführen.
  • @ ctrl-alt-delor: Als ich Ende 80 an der Universität war ‚ s, dies war eine übliche (verbotene) Taktik. Schreiben Sie ein “ ls “ -Programm und lassen Sie es in Ihrem Home-Ordner, falls jemand anderes schnüffelt. Das Programm wurde als “ get-Shell “ IIRC bezeichnet. Es würde versuchen, die Anmeldeinformationen des Benutzers abzurufen, der den Befehl ausführt – und dann möglicherweise eine gefälschte Verzeichnisliste drucken, um sie nicht zu bemerken.

Antwort

Die wörtliche Antwort lautet wie von anderen angegeben: Da das aktuelle Verzeichnis nicht in Ihrem $PATH enthalten ist.

Aber Warum? Kurz gesagt, es dient der Sicherheit. Wenn Sie im Home-Verzeichnis (oder / tmp) einer anderen Person suchen und nur gcc oder ls eingeben, möchten Sie dies tun Sie wissen, dass Sie die echte Version ausführen, keine böswillige Version, die Ihr Scherzfreund geschrieben hat und die alle Ihre Dateien löscht. Ein weiteres Beispiel wäre test oder [, das diese Befehle in Shell-Skripten möglicherweise überschreibt, wenn Ihre Shell diese nicht als integrierte Funktionen hat.

Mit . als letzter Eintrag in Ihrem Pfad ist etwas sicherer, aber es gibt andere Angriffe, die davon Gebrauch machen. Eine einfache Möglichkeit besteht darin, gängige Tippfehler wie sl oder ls-l auszunutzen. Oder suchen Sie einen allgemeinen Befehl, der zufällig nicht auf diesem System installiert ist – vim, da Sysadmins mit überdurchschnittlicher Wahrscheinlichkeit diesen eingeben.

Klingt das zu theoretisch? Es ist größtenteils , aber es kann definitiv in der Realität passieren, insbesondere auf Mehrbenutzersystemen. Tatsächlich ist hier ein Beispiel von dieser Site , bei der ein Administrator in das Home-Verzeichnis eines Benutzers gewechselt ist und ps gefunden hat von einer ausführbaren Datei dieses Namens maskiert werden.

Kommentare

  • Nur absolute Pfade in der PATH Umgebungsvariable.

Antwort

Wenn Sie meinen, warum brauchen Sie./ am Anfang – das liegt daran, dass das aktuelle Verzeichnis (anders als in Windows) standardmäßig nicht Teil Ihres Pfads ist. Wenn Sie Folgendes ausführen:

$ ls 

sucht Ihre Shell in den Verzeichnissen Ihrer Umgebungsvariablen PATH (iv.) Nach ls id = „b0ea2fff81“>

, um es zu sehen) und führt die erste ausführbare Datei mit dem Namenlsaus, die es findet. Wenn Sie Folgendes eingeben:

$ a.out 

funktioniert die Shell ebenfalls – aber es wird wahrscheinlich keine ausführbare Datei mit dem Namen a.out gefunden. Sie müssen der Shell mitteilen, wo a.out is – es befindet sich im aktuellen Verzeichnis (.), dann lautet der Pfad ./a.out.

Wenn Sie fragen, warum es aufgerufen wird „a.out“, das ist nur der Standardname der Ausgabedatei für gcc. Sie können ihn mit dem Befehlszeilenargument -o ändern. Beispiel:

$ gcc test.c -o test $ ./test 

Kommentare

  • Danke. Mein Zweifel ist, warum Sie ./ am Anfang brauchen … Ich habe die Verwendung von „. “ (um das aktuelle Verzeichnis zu speichern), aber warum “ / “ danach?
  • / ist das Pfadtrennzeichen in Linux, also verwenden Sie es, um das Verzeichnis (.) vom Dateinamen (a.out) zu trennen. Ohne es haben Sie .a.out, das gültig ist Dateiname für sich. (Versuchen Sie touch .a.out; ls -lA, dies zu sehen.)
  • So geben Sie den an Pfad in Unix, <dir>/<file> Sie sagen also im Grunde, führen Sie eine Datei im aktuellen Verzeichnis aus, was durch ./test
  • Red Hat Linux 9? Zeit für ein Upgrade!

  • Unter Windows 10 ist PowerShell jetzt die Standard-Shell und erfordert außerdem ./, um eine ausführbare Datei im aktuellen Pfad
  • Antwort

    Sie können versuchen, Ihrer $ PATH-Variablen :. hinzuzufügen.

    Versuchen Sie ALT + F2 und geben Sie Folgendes ein: gksudo gedit /etc/environment, wenn Sie Linux / GTK ausführen (dies ist das, was Sie haben, wenn Sie Ubuntu verwenden).

    JEDOCH, Ich rate Ihnen dringend, dies NICHT zu tun. Es ist schlecht, schlecht, schlecht und schlecht.

    Sie wissen, dass solche Dinge seit 1970 so funktionieren. Es gibt einen Grund, warum das aktuelle Verzeichnis nicht im $ PATH enthalten ist.

    . ist das aktuelle Verzeichnis

    .something wäre eine versteckte Datei (Geben Sie „ALT +“ ein Sie werden in Nautilus angezeigt oder versuchen Sie „ls -la„.

    ./someProgram.sh geben Sie ein, um ein ausführbares Programm auszuführen .sh im aktuellen Verzeichnis.

    .somethingElse würde bedeuten, dass Sie eine versteckte ausführbare Datei im aktuellen Verzeichnis haben, was eine schlechte Idee ist.

    Antwort

    Die vollständigere Regel lautet tatsächlich: Wenn ein Schrägstrich / befindet sich im Pfad. Suchen Sie nicht nach PATH

    , bevor wir fortfahren Aus diesem Grund sollten Sie zunächst Folgendes wissen: Ausführen von:

    bin/someprog 

    oder:

    oder:

    cd bin ./myexec 

    bin/someprog ausführen, ohne die PATH Variable aus genau demselben Grund: alle bin/someprog, /bin/someprog und ./someprog enthält einen Schrägstrich /.

    someprog allein enthält keinen Schrägstrich / und sucht daher nur in PATH.

    POSIX 7 gibt diese Regel an unter: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01_01

    PATH

    […] Wenn der gesuchte Pfadname eine <slash> enthält, darf die Suche durch die Pfadpräfixe nicht durchgeführt werden

    Begründung für die / POSIX PATH-Regel

    Angenommen, Folgendes wird ausgeführt:

    someprog 

    würde suchen:

    • relativ zu CWD zuerst
    • relativ zu PATH nach

    Dann, wenn Sie /bin/someprog von Ihrer Distribution, und Sie haben Folgendes getan:

    someprog 

    es würde manchmal funktionieren, aber bei anderen würde es fehlschlagen, weil Möglicherweise befinden Sie sich in einem Verzeichnis, das ein anderes nicht verwandtes someprog -Programm enthält.

    Daher würden Sie bald feststellen, dass dies nicht zuverlässig ist, und Sie würden es am Ende immer verwenden Absolute Pfade, wenn Sie PATH verwenden möchten, wodurch der Zweck von PATH zunichte gemacht wird.

    Dies ist auch der Grund, warum es eine wirklich schlechte Idee ist, relative Pfade in Ihrem PATH zu haben. Ich sehe Sie mit an, node_modules/bin .

    Nehmen wir umgekehrt an, dass Folgendes ausgeführt wird:

    ./someprog 

    würde suchen:

    • relativ zu PATH first
    • relativ zu CWD nach

    Wenn Sie dann gerade ein Skript someprog aus einem Git-Repository heruntergeladen haben und es ausführen möchten Von CWD aus würden Sie niemals sicher sein, dass dies das eigentliche Programm ist, das ausgeführt wird, da Ihre Distribution möglicherweise Folgendes hat:

    /bin/someprog 

    , aus dem sich Ihr Pfad ergibt Einige Pakete, die Sie installiert haben, nachdem Sie nach Weihnachten im letzten Jahr zu viel getrunken haben.

    Daher müssten Sie erneut lokale Skripte relativ zu CWD mit vollständigen Pfaden ausführen, um zu wissen, was Sie ausführen:

    "$(pwd)/someprog" 

    , was ebenfalls äußerst ärgerlich wäre.

    Eine andere Regel, die Sie möglicherweise in Versuchung führen könnten, wäre:

    relative Pfade verwenden nur PATH, absolute Pfade nur CWD

    , aber dies zwingt Benutzer erneut dazu Verwenden Sie immer abso Lautenpfade für Nicht-PATH-Skripte mit "$(pwd)/someprog".

    Die Pfadsuchregel / bietet eine einfach zu merkende Lösung zum About-Problem:

    • Schrägstrich: Verwenden Sie nicht PATH
    • kein Schrägstrich: Verwenden Sie nur PATH

    , wodurch es sehr einfach ist, immer zu wissen, was Sie ausführen, indem Sie sich darauf verlassen, dass Dateien im aktuellen Verzeichnis entweder als ./somefile oder somefile, und daher gibt es einem von ihnen eine besondere Bedeutung.

    Manchmal ist es etwas ärgerlich, dass Sie nicht suchen können für some/prog relativ zu PATH, aber ich sehe keine vernünftigere Lösung dafür.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.