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 rm
oder rmdir 'this_is_link/'
der gleiche Fehler Not a directory
tritt 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?
Antworten:
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 definiertfoo/.
(für Pfadauflösungszwecke, nicht beim Bearbeiten von Dateinamenbasename
unddirname
Ignorieren 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 zurm 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.quelle
Meine Einstellung:
Ü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.
quelle
rm
Ruft stat auf (naja, newfstatat, eigentlich mit derAT_SYMLINK_NOFOLLOW
Option) und weigert sich, weiterzumachen, während rmdir tatsächlich rmdir (2) aufruft, aber bekommtENOTDIR
.AT_SYMLINK_NOFOLLOW
verhindert, dass es dem Symlink folgt. Daher sollte rm den Link selbst löschen, anstatt "Kein Verzeichnis" zu drucken, das nicht den Umständen entspricht.stat
undstat -L
unterscheidet sich nur, wenn das Argument ohne einen abschließenden Schrägstrich angegeben wird.rm
verhält es sich richtig undrmdir
ist es nicht. Das Trailing/
sollte sie zwingen, ihr Argument gemäß dem POSIX-Standard als Verzeichnis zu behandeln. Siehe meine Antwort für Referenzen .