Gibt es einen Unterschied zwischen den Pfaden "file" und "./file"?

12

Gibt es, wie aus dem Titel hervorgeht, einen Unterschied für * NIX-Dateisysteme? zB ls fileundls ./file

Sergey Alaev
quelle
1
Sie könnten nach unix.stackexchange.com fragen - die Antworten enthalten bis jetzt alle gute Informationen, aber keiner von beiden fühlt sich wirklich nach der Antwort an.
Rob Starling

Antworten:

14

Ich bin nicht verrückt nach der Erklärung von SmallLoanOf1M. Es ist technisch korrekt, aber die Antworten stimmen nicht mit dem Verwendungsbeispiel in der Frage überein.

Als Beispiel ist hier ein wichtiger Unterschied zwischen den beiden von der Frage: "Datei" und "./Datei"

Was ist, wenn die Datei mit einem Zeichen benannt ist, das von der Shell analysiert wird? Insbesondere in Bezug auf Zeichen, die vom Befehl interpretiert werden, wird ausgeführt.

Insbesondere das "Bindestrich" -Zeichen: "-". Aber andere Zeichen sind für die Shell von Bedeutung.

Beispiel. Meine Datei hieß "-dingle"

Versuchen Sie, die Datei aufzulisten:

ls -dingle
# ls -dingle
ls: invalid option -- 'e'

Schlimmer noch, was ist, wenn die Datei den Namen " -rf rmbomb *" trägt? Versuchen Sie nun, es zu entfernen

rm "-rf rmbomb *"

Ich werde nicht einmal versuchen, dieses Beispiel auszuführen, aber ich hoffe, Sie haben die Idee.

Wie listet man eine Datei auf, die mit einem Bindestrich versehen ist? Verwenden Sie ./vor.

# ls ./-dingle
./-dingle

Das Gleiche gilt für rm

JDS
quelle
Das ist eine gültige Methode, um einige Dateien mit ungeraden Namen zu verarbeiten, und meine Antwort berücksichtigte solche Dateien nicht. In allen obigen Beispielen kann stattdessen auch ein Literal in Form eines umgekehrten Schrägstrichs vor ungeraden Zeichen einschließlich der oben angegebenen Leerzeichen verwendet werden. Ein Beispiel dafür wäre: ls \-dingleoder ls \-rf\ rmbomb\ \*. Dies kann eine gute Möglichkeit sein, um sicherzustellen, dass alle angegebenen Befehlssätze mindestens konsistent sind, da die Angabe ./vor einem Namen nach dem Zeichen kein Escapezeichen darstellt ./.
Spooler
2
Es kommt vor, dass, da Escape-Zeichen von der Shell und nicht vom Befehl maskiert werden und Params vom Befehl analysiert werden, escape-Zeichen oder Anführungszeichen von - nichts Sinnvolles tun.
Dewi Morgan
2
Sie lassen es so klingen, als rm "-rf rmbomb *"würde es tatsächlich etwas Schlechtes tun, anstatt nur rmeinen Fehler beim Drucken zu verursachen. Es ist nur gefährlich, wenn Sie vergessen, den Dateinamen in Anführungszeichen zu setzen. (Insbesondere in einem Shell-Skript, in dem Sie rm $filestattdessen ausführen rm "$file". In diesem Fall wird das Skript *jedoch nicht erweitert, da bei den Inhalten der Variablenerweiterung keine Glob-Erweiterung stattfindet. Wenn Sie dies möchten, benötigen Sie ein eval.) Wie auch immer, wenn Ihr Skript die Dateinamen mit einem Wort aufteilt, bevor sie an rm übergeben werden, würde ich eine Datei mit dem Namen space -rf .oder so machen, das rm ./$ihilft nichts.
Peter Cordes
1
Übrigens ist die eigentliche Fehlermeldung rm: invalid option -- ' ', wenn versucht wird, das Leerzeichen danach -rfals ein Zeichen zu interpretieren , da es Teil desselben Arguments ist. (Und ja, ich habe dies in einem leeren Verzeichnis ausgeführt, nur für den Fall, dass ich etwas übersehen hatte und es tatsächlich gefährlich war: P)
Peter Cordes
2
@PeterCordes: Wordsplitting und Globbing-DOES treten bei den Ergebnissen der nicht zitierten Variablenerweiterung und der Befehlssubstitution auf, sofern sie nicht durch IFS=''und unterdrückt werden -f. Ein selteneres Beispiel ist, dass awkein Operand (außer einem ersten Operanden, bei dem es sich um das Skript handelt) mit einer Form foo=barals auszuführende Zuweisung, aber ./foo=barals zu lesende Datei behandelt wird.
Dave_thompson_085
7

Ja.

Durch die Ausgabe filein der Befehlszeile durchsucht BASH Ihre Umgebungsvariable $ PATH nach einer Datei mit diesem Namen. Sofern sich die Datei nicht in einem Verzeichnis innerhalb Ihrer $ PATH-Variablen befindet, wird sie nicht gefunden.

.bedeutet das aktuelle Verzeichnis. ./bedeutet innerhalb des aktuellen Verzeichnisses, in relativen Begriffen. Es ist das Äquivalent dazu, etwas zu sagen, wie /home/sheogorath/shivering/isles.imgbeim Aufrufen ./isles.imgwährend der Arbeit im /home/sheogorath/shivering/Verzeichnis.

Daher wird es häufig verwendet, um Dateien in Ihrem Arbeitsverzeichnis "an Ort und Stelle" auszuführen.

EDIT: In Ihrem Beispiel lswird von der Shell aufgerufen und mithilfe der Pfadvariablen gefunden. Das Argument wird in Ihrem Arbeitsverzeichnis verarbeitet, wie auch immer das sein mag. Da dies die Standardeinstellung für ist ls, werden Sie keinen Unterschied zwischen dem Angeben fileund dem expliziten Angeben feststellen, ./fileda beide auf Ihr aktuelles Verzeichnis verweisen.

Nicht alle Befehle akzeptieren Dateipfade im Arbeitsverzeichnis, und einige erwarten, dass Sie Dateien in einem Verzeichnis angeben, das sie selbst über die Konfiguration vordefinieren. Unter Befehlen, die Dateien als Argumente akzeptieren, sind diese Befehle weniger verbreitet

Spooler
quelle
1
Das ist heftig, aber ich habe mich über die
Pfadauflösung
1
Das ist die Art und Weise, wie ich jemals von Werken gehört habe. BASH wird nur am häufigsten verwendet.
Spooler
4
$ PATH ist nur für Befehle relevant und hat nichts mit Dateinamenargumenten zu tun, die auf einen Befehl folgen, wie er lsin der ursprünglichen Frage erwähnt wurde. Das ist eher der Unterschied zwischen dem Verweisen auf einen relativen Pfad (relativ zum aktuellen Arbeitsverzeichnis), d. ../../dir/filename /path/to/dir/filename
H.,
1
+1 für Sheogorath ... und eine richtige Antwort.
Corey Ogburn
1
Wenn es sich um Argumente für einen Befehl handelt, der standardmäßig versucht, Dateien im Arbeitsverzeichnis zu finden, sind sie identisch. Daher ist lses immer derselbe Pfad, von dem einer expliziter als der andere angegeben wird. Nicht alle Befehle verhalten sich bei der Verarbeitung von Argumenten so, die meisten jedoch.
Spooler