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önntenls
zum Beispiel (ein einfacher Virus / Trojen: Erstellen Sie eine Zip-Datei mit einer ausführbaren Datei namensls
, 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 Namenls
aus, 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
- Unter Windows 10 ist PowerShell jetzt die Standard-Shell und erfordert außerdem
./
, um eine ausführbare Datei im aktuellen Pfad - relativ zu CWD zuerst
- relativ zu PATH nach
- relativ zu PATH first
- relativ zu CWD nach
- Schrägstrich: Verwenden Sie nicht
PATH
- kein Schrägstrich: Verwenden Sie nur
PATH
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:
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:
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:
, 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.