Nachgestellte Schrägstriche bei symbolischen Links zu Verzeichnissen

8

Ich versuche, den Prozess der Pfadauflösung (siehe Manpage path_resolution) in Unix-ähnlichen Systemen zu emulieren.

Mein Betriebssystem ist Linux mit GNU Coreutils 8.7.

Um die Bedeutung eines zusätzlichen nachgestellten '/' in der Auflösung zu verdeutlichen, habe ich folgende Dinge in einer Shell getan:

mkdir this_is_dir
ln -s this_is_dir this_is_link
rm this_is_link

Alles war in Ordnung, da this_is_link ein Symlink ist und ich ihn einfach entfernt habe. Aber beim Versuch:

mkdir this_is_dir
ln -s this_is_dir this_is_link
rm this_is_link/

Es hallte wider rm: cannot remove 'this_is_link/': Is a directory

Nun, das nachfolgende '/' verursachte das Folgen von Symlink, dachte ich. Also habe ich einen anderen Befehl ausprobiert:rmdir this_is_link/

Und ein lustiges Ergebnis kam heraus: rmdir: failed to remove 'this_is_link/': Not a directory

Nicht das was ich erwartet habe. Also bat ich meinen Freund zu bestätigen, ob das gleiche Ergebnis auf seinem System erzielt werden konnte. Er hatte eine niedrigere Version von Coreutils als ich. Und das Ergebnis war erstaunlich, egal rmoder rmdir 'this_is_link/'der gleiche Fehler Not a directorytritt auf .

Und ein anderer Freund hat es gerade unter Mac OS ausprobiert. Das Ergebnis ist: rm=> 'Ist ein Verzeichnis', rmdir=> das Verzeichnis wurde erfolgreich gelöscht, der Link blieb erhalten .

Gibt es Angaben zum genauen Verhalten der Pfadauflösung?

ymfoi
quelle

Antworten:

7

Die POSIX / Single Unix-Spezifikation gibt an, dass ein Pfadname mit einem abschließenden Schrägstrich auf ein Verzeichnis verweisen muss (siehe Basisdefinitionen §4.11 Pfadnamenauflösung ). foo/wird in der Tat als äquivalent zu definiert foo/.(für Pfadauflösungszwecke, nicht beim Bearbeiten von Dateinamen basenameund dirnameIgnorieren von nachgestellten Schrägstrichen). Die meisten Implementierungen berücksichtigen dies, es gibt jedoch einige Ausnahmen.

Dies erklärt das Verhalten von rm this_is_link/: Es ist äquivalent zu rm this_is_link/., wobei das Argument eindeutig ein Verzeichnis ist.

rmdir this_is_link/sollte sich ebenfalls auf das Verzeichnis beziehen. Dass dies auf Ihrem Computer nicht der Fall ist, ist ein Fehler in GNU-Coreutils. OSX verhält sich hier korrekt.

Gilles 'SO - hör auf böse zu sein'
quelle
Genau das habe ich gebraucht, danke!
ymfoi
-1

Meine Einstellung:

  • '' rm link / '' schlägt fehl, weil rm auf das letzte Zeichen schaut, sieht, dass es ein Schrägstrich ist, und die (nicht wirklich korrekte) Diagnose gibt, die Sie gesehen haben;
  • '' rmdir link / '' schlägt in Ordnung fehl: link ist kein Verzeichnis, es ist ein Symlink
  • '' rm link '' wird korrekt erfolgreich sein

Übrigens hat die Pfadauflösung sehr wenig damit zu tun, sie scheint nur "rm" zu sein, anstatt (richtig) "stat" für ein Argument aufzurufen (was rmdir tut).

Prost.

Alien Lebensform
quelle
1
Tatsächlich scheint das Gegenteil der Fall zu sein: rmRuft stat auf (naja, newfstatat, eigentlich mit der AT_SYMLINK_NOFOLLOWOption) und weigert sich, weiterzumachen, während rmdir tatsächlich rmdir (2) aufruft, aber bekommt ENOTDIR.
Ansgar Esztermann
@AnsgarEsztermann AT_SYMLINK_NOFOLLOWverhindert, dass es dem Symlink folgt. Daher sollte rm den Link selbst löschen, anstatt "Kein Verzeichnis" zu drucken, das nicht den Umständen entspricht.
ymfoi
Nach einer kurzen Überprüfung mit stat (1) überschreibt der abschließende Schrägstrich die Option. Die Ausgabe von statund stat -Lunterscheidet sich nur, wenn das Argument ohne einen abschließenden Schrägstrich angegeben wird.
Ansgar Esztermann
@AnsgarEsztermann Oh, ich verstehe ... Thx. Wie wäre es mit den unterschiedlichen Auswirkungen auf die unterschiedliche Umgebung? Irgendwelche Ideen?
ymfoi
1
Es ist das Gegenteil: Auf ymfois Maschine rmverhält es sich richtig und rmdirist es nicht. Das Trailing /sollte sie zwingen, ihr Argument gemäß dem POSIX-Standard als Verzeichnis zu behandeln. Siehe meine Antwort für Referenzen .
Gilles 'SO - hör auf böse zu sein'