Pfadsyntaxregeln

10

Ich schreibe eine Bibliothek zur Bearbeitung von Unix-Pfadzeichenfolgen. In diesem Fall muss ich einige dunkle Ecken der Syntax verstehen, über die sich die meisten Menschen keine Sorgen machen würden.

Zum Beispiel, so gut wie ich sagen kann, scheint es , dass foo/barund foo//barbeide auf die gleiche Stelle.

Auch ~in die Regel steht für den Home - Verzeichnis des Benutzers, aber was , wenn es in der erscheint Mitte eines Weges? Was passiert dann?

Diese und einige Dutzend andere obskure Fragen müssen beantwortet werden, wenn ich Code schreiben möchte, der jeden möglichen Fall korrekt behandelt. Kennt jemand eine endgültige Referenz, die die genauen Syntaxregeln für dieses Zeug erklärt?

(Leider werden bei der Suche nach Begriffen wie "Unix-Pfadsyntax" nur eine Million Seiten mit der $PATHVariablen angezeigt ... Ich habe sogar Probleme, geeignete Tags für diese Frage zu finden!)

MathematicalOrchid
quelle
Die Erweiterung ok ~ tilde und -filename liegen den von POSIX definierten Funktionen jeder Unix-Umgebung zugrunde. Ein paar Tipps: Ein Dateiname kann alles andere als \ 0 oder / sein. ////// und / sind dasselbe. $ PWD wird im Kernel behandelt und kann für jeden (Linux-) Prozess in / proc gelesen werden . /./ kann nur an der Wurzel eines Pfades auftreten. In $ PATH ::::: und: sind dasselbe. / dev / null / dev / tty und / tmp sind POSIX-garantierte Pfade für jedes konforme System.
Mikeserv
1
Der größte Teil Ihrer Frage (aber nicht der Teil über ~) wird in Wie Linux mit mehreren Pfadtrennzeichen (/ home //// Benutzername /// Datei) umgeht behandelt . Das, was einer normativen Referenz am nächsten kommt, ist die POSIX- oder Single Unix-Spezifikation - nicht einfach zu lesen.
Gilles 'SO - hör auf böse zu sein'

Antworten:

13

Es gibt drei Arten von Pfaden:

  • Relativ Pfade wie foo, foo/bar, ../a, .. Sie beginnen nicht mit /und beziehen sich auf das aktuelle Verzeichnis des Prozesses, der einen Systemaufruf mit diesem Pfad ausführt.
  • absolute Pfade wie /, /foo/baroder ///x. Sie beginnen mit 1 oder 3 oder mehr /, sind nicht relativ und werden ausgehend vom /Stammverzeichnis nachgeschlagen .
  • POSIX kann //foospeziell behandelt werden, gibt jedoch nicht an, wie. Einige Systeme verwenden dies für spezielle Fälle wie Netzwerkdateien . Es müssen genau 2 Schrägstriche sein.

Anders als zu Beginn wirken Schrägstrichsequenzen wie eine.

~ist nur etwas Besonderes für die Shell , es wird durch die Shell erweitert, es ist überhaupt nichts Besonderes für das System. Wie es erweitert wird, hängt von der Shell ab. Shells führen andere Formen von Erweiterungen durch, z. B. globbing ( *.txt) oder variable Erweiterung /$foo/$baroder andere. Für das System ist ~fooes nur ein relativer Pfad wie _foooder foo.

Dinge zu beachten:

  • foo/ist nicht dasselbe wie foo. Es ist näher foo/.als foo(insbesondere wenn fooes sich um einen Symlink handelt) für die meisten Systemaufrufe auf den meisten Systemen ( foo//ist das gleiche wie foo/wenn).
  • a/b/../cist nicht unbedingt dasselbe wie a/c(zum Beispiel wenn a/bes sich um einen Symlink handelt). Am besten nicht ..speziell behandeln .
  • Es ist im Allgemeinen sicher, a/././././bdasselbe als a/bob zu betrachten.
Stéphane Chazelas
quelle
Wenn ich mich also nicht um die Manipulation von Shell-Pfaden kümmere (was sehr umfangreich und kompliziert ist), muss ich mich nur darum kümmern /, .und ..(?)
MathematicalOrchid
Ein Beispiel für die //fooBehandlung ist Cygwin, wo es für UNC-Pfade verwendet wird . Das heißt, es //server/share/dir/file.txthandelt sich um einen legalen Pfad, der standardmäßig auf das System verweist. Cygwin greift auf das lokale System zurück, wenn es nicht gefunden werden kann server.
Warren Young
3

Zum Beispiel, so gut ich das beurteilen kann, scheinen foo / bar und foo // bar beide auf dieselbe Stelle zu zeigen.

Ja. Dies ist häufig der Fall, weil Software manchmal einen Pfad verkettet, vorausgesetzt, der erste Teil wurde nicht mit einem Schrägstrich abgeschlossen, sodass einer eingeworfen wird, um sicherzugehen (was bedeutet, dass möglicherweise zwei oder mehr vorhanden sind). foo///barund zeigen Sie foo/////barauch auf den gleichen Ort wie foo/bar. Eine nette Funktion für eine Pfadmanipulationsbibliothek wäre eine, die eine beliebige Anzahl von aufeinanderfolgenden Schrägstrichen auf eins reduziert (außer am Anfang eines Pfades, wo sie auf URL-artige Weise verwendet werden kann, oder, wie Stephane betont, für eine beliebige nicht näher bezeichneter Sonderzweck).

Außerdem steht ~ normalerweise für das Home-Verzeichnis des Benutzers

Diese Transformation erfolgt über die Shell- und Tilde-Erweiterung , die nur funktioniert, wenn es sich um das erste Zeichen im Pfad handelt. Ob Sie sich damit befassen müssen oder nicht, hängt vom Kontext ab. Wenn die Bibliothek mit normalen Programmen verwendet werden soll, die z. B. Befehlszeilenargumente empfangen, die einen Pfad enthalten, wird die Tilde-Erweiterung bereits durchgeführt, wenn sie den Pfad sehen. Die einzige Situation, die ich als bedenklich erachte, ist, wenn Sie Pfade direkt aus einer Textdatei verarbeiten.

Darüber hinaus ~ist es ein rechtlicher Charakter in einem * nix-Pfad und sollte nicht in etwas anderes geändert werden. Aus diesem/ Grund sind die einzigen Zeichen, die in einem Unix-Dateinamen nicht zulässig sind (weil es sich um das Pfadtrennzeichen handelt) und "null" (auch bekannt als Null-Byte), da sie im Text im Allgemeinen unzulässig sind.

Goldlöckchen
quelle
+1 zur Erklärung der Tildeexpansion; Ich hatte keine Ahnung, dass Sie damit auf andere Benutzer verweisen könnten !
MathematicalOrchid
2
Wie Stephane sagt, können Sie nicht alle wiederholten Schrägstriche blind zusammenklappen. Mehrere Schrägstriche am Anfang des Pfades müssen sorgfältig behandelt werden.
Warren Young
@WarrenYoung Bearbeitet, um dies klar zu machen. PS. Nach vorne??! O_O
Goldlöckchen
Besser, obwohl ich nicht sagen würde, dass dies etwas mit URLs zu tun hat. UNC geht auf die späten 1980er Jahre zurück, während URLs erst Jahre später auftauchten.
Warren Young
@WarrenYoung Fair genug, obwohl es den Anschein hat, dass UNCs spezifisch für MS-Plattformen sind , //ist dies technisch auch nicht der Fall. Sowohl URLs als auch die neuere, laut SC frei mehrdeutige POSIX-Spezifikation für // können von solchen abgeleitet worden sein. In diesem Fall scheint "URL-ish" eine passende Bezeichnung für die Konvention zu sein (selbst wenn UNCs älter sind und selbst wenn der Anschein besteht ist unbeabsichtigt). Ich würde niemals sagen, dass "sie URLs sind", nur das //oder \\ einem "URL-ish" Zweck dient.
Goldlöckchen