In der folgenden Situation ls -alh
total 0
drwxrwx--- 1 user http 20 Nov 30 08:08 .
drwxrws--- 1 user http 310 Nov 30 08:07 ..
drwx------ 1 http http 10 Nov 30 08:08 empty-subdir
drwx------ 1 http http 12 Nov 30 08:08 non-empty-subdir
wo zwei Unterverzeichnisse existieren (nicht in meinem Besitz), die ich aufführe als:
sudo ls empty-subdir -alh
total 0
drwx------ 1 http http 10 Nov 30 08:08 .
drwxrwx--- 1 user http 20 Nov 30 08:08 ..
sudo ls non-empty-subdir -alh
total 0
drwx------ 1 http http 12 Nov 30 08:08 .
drwxrwx--- 1 user http 20 Nov 30 08:08 ..
drwx------ 1 http http 0 Nov 30 08:08 subdir
Der Unterschied zwischen den beiden Unterverzeichnissen besteht darin, dass das nicht leere Verzeichnis non-empty-subdir
einen Ordner enthält.
Meine Frage ist, ob rm -rf
ich beim Versuch , die Unterverzeichnisse zu entfernen, beabsichtigt Ergebnisse erhalte:
$ rm empty-subdir -rf
$ rm non-empty-subdir -rf
rm: cannot remove 'non-empty-subdir': Permission denied
$ ls -alh
total 0
drwxrwx---+ 1 user http 10 Nov 30 08:14 .
drwxrws---+ 1 user http 310 Nov 30 08:07 ..
drwx------+ 1 http http 12 Nov 30 08:08 non-empty-subdir
Es scheint, dass der Benutzer mit Schreibberechtigungen für ein Verzeichnis einen Eintrag für eine Datei oder ein leeres Unterverzeichnis eines anderen Benutzers entfernen darf, jedoch kein nicht leeres Unterverzeichnis.
Eine ideale Antwort auf diese Frage würde Informationen liefern wie:
- eine Bestätigung, dass das beschriebene Verhalten auf anderen Maschinen reproduzierbar ist (und nicht nur Macken meiner vermasselten Box)
- eine Begründung, um dieses Verhalten zu erklären (z. B. gibt es Anwendungsfälle?)
- eine Übersicht, wenn es Unterschiede zwischen Systemen gibt (BSD, Linux ....)
Update : In Bezug auf den Kommentar von Ipor Sircer habe ich das Szenario ohne ACL-Funktionen erneut getestet und es ist dasselbe. Ich habe daher die Frage geändert, um die +
es aus den Auflistungen zu entfernen, damit nicht die Idee entsteht, dass das Verhalten mit ACLs zusammenhängt.
quelle
+
Zeichen bedeutet, dass ACLs (Access Control List) -Berechtigungen vorhanden sind, die von aufgelistet werden könnengetfacl <directory>
.Antworten:
Ein Verzeichnis (mit dem
rmdir()
Systemaufruf) kann nur entfernt werden, wenn es leer ist.rm -r dir
Entfernt das Verzeichnis und alle darin enthaltenen Dateien, beginnend mit den Blättern des Verzeichnisbaums und bis zum Stammverzeichnis (dir
).Um eine Datei zu entfernen (mit
rmdir()
für Verzeichnisse undunlink()
für andere Dateitypen oder*at()
Varianten), ist es nicht die Berechtigung der Datei selbst, sondern die des Verzeichnisses, aus dem Sie die Datei entfernen (beachten Sie dast
Bit in den Berechtigungen, wie z für/tmp
, fügt dem weitere Komplikationen hinzu).Vor allem entfernen Sie die Datei nicht wirklich, sondern trennen sie aus einem Verzeichnis (und wenn es der letzte Link ist, den Sie entfernen, wird die Datei in der Folge gelöscht), das heißt, Sie sind es Wenn Sie das Verzeichnis ändern, müssen Sie die Berechtigungen für dieses Verzeichnis ändern (schreiben).
Der Grund, den Sie nicht entfernen können,
non-empty-dir
ist, dass Sie die Verknüpfung nicht zuerst trennensubdir
können, da Sie nicht das Recht haben, Änderungen vorzunehmennon-empty-dir
. Sie haben das Recht, die Verknüpfung zunon-empty-dir
Ihrem Ausgangsverzeichnis aufzuheben, da Sie über eine Schreib- / Änderungsberechtigung für dieses Verzeichnis verfügen. Sie können jedoch kein Verzeichnis entfernen, das nicht leer ist.In Ihrem Fall
rmdir()
schlägt der Systemaufruf , wie von @PeterCordes in den Kommentaren angegeben, mit einemENOTEMPTY
Fehlercode (Verzeichnis nicht leer) fehl. Da Sie jedoch keine Leseberechtigung für das Verzeichnis haben,rm
können Sie nicht einmal herausfinden, welche Dateien und Verzeichnisse (einschließlichsubdir
) Es müsste die Verknüpfung aufheben, um es leeren zu können (nicht, dass es die Verknüpfung aufheben könnte, wenn es wüsste, da es keine Schreibberechtigungen hat).Sie können auch in Situationen geraten, in denen ein Verzeichnis entfernt werden
rm
könnte , wenn nur herausgefunden werden könnte, welche Dateien sich darin befinden, wie im Fall eines Nur-Schreib-Verzeichnisses:Trotzdem kann ich es entfernen, da ich zufällig weiß, dass es nur eine
file
Datei enthält :Beachten Sie auch, dass Sie dies mit modernen Unices umbenennen können
non-empty-dir
, aber unter Linux oder FreeBSD (aber nicht mit Solaris) nicht in ein anderes Verzeichnis verschieben können, selbst wenn Sie auch Schreibberechtigung für dieses Verzeichnis hatten, wie (glaube ich und für Linux) , wie im Kommentar für den entsprechenden Code vorgeschlagen , würde dies eine Änderung beinhaltennon-empty-dir
(der..
Eintrag darin würde auf ein anderes Verzeichnis verweisen).Man könnte argumentieren, dass das Entfernen Ihrer
empty-dir
auch das Entfernen der..
und.
Einträge darin beinhaltet, also ändern Sie es, aber dennoch können Sie dies vom System tun.quelle
rm: cannot remove 'non-empty-subdir': Permission denied
ist, dass das OP keine Leseberechtigung für das Verzeichnis hat und daherrm
nicht einmal seinen Inhalt auflisten konnte , um zu versuchen , seinen Inhalt zu entfernen. Wenn es dieo+r
Erlaubnis hätte (zB 755 oder sogar 744), wäre die Fehlermeldung leuchtender gewesen, wie z... 'non-empty-subdir/subdir': Permission denied
. Aus diesem Grund habe ich die Frage positiv bewertet.rm
nicht einmal sehen kann, dassnon-empty-dir
das nicht leer ist. Die Anzahl der Links in den OPs istls -alh
alle1
, auch für Verzeichnisse (Schein), aber wenn das Verzeichnis ein Nicht-Verzeichnis enthalten hätte, könnten Sie immer noch nicht den Unterschied zwischen einem leeren und einem nicht leeren Verzeichnis erkennen, wenn Sie es nicht lesen können. (Außer durch den Versuch, es zu entfernen.)rename
das Verzeichnis könnte, das sie nicht besitzen, weil (ohne dast
Sticky-Bit) dies nur eine Schreibberechtigung für das Verzeichnis erfordert, das sie besitzen.Wenn ich die mögliche Änderung durch die ACLs ignoriere, kann ich dieses Verhalten für mein System (ohne ACLs) bestätigen.
Das beobachtete Verhalten ist die logische Konsequenz zweier Prinzipien:
1) Die Rechte für ein Verzeichnis bestimmen, wer das Verzeichnis ändern kann, dh Einträge im Verzeichnis löschen. Die Rechte der Einträge in diesem Verzeichnis spielen dabei keine Rolle.
2) Das Entfernen einer Datei erfordert möglicherweise das Entfernen und Bereinigen der zugehörigen Informationen, z. B. Inodes, Blockzuweisungslisten usw. Aus diesem Grund können Sie eine nicht leere Unterverzeichnis nicht entfernen, ohne alle darin enthaltenen Dateien bereinigt zu haben, da sonst die darin enthaltenen Dateien bereinigt würden unzugänglich werden, aber die zugehörigen Informationen wären nicht bereinigt worden.
Sie können also entfernen
empty-subdir
, weil Sie die Rechte haben, in das Verzeichnis zu schreiben, in dem es sich befindet. Sie können nicht entfernennon-empty-subdir
, weil Sie nicht die Rechte haben, die in diesem Unterverzeichnis enthaltenen Dateien zuerst zu bereinigen.Es gibt wirklich keine Gründe oder Anwendungsfälle dafür. Man hätte eine rekursive Bereinigung eines Unterverzeichnisses in den Kernel einbauen können, aber das ursprüngliche Unix hielt alles einfach, und eine rekursive Bereinigung wäre zu kompliziert gewesen, wenn sie mit einem User-Space-Dienstprogramm erreicht werden könnte.
Ich kann keinen umfassenden Überblick zwischen verschiedenen Geschmacksrichtungen geben, aber dies war das Verhalten in der ursprünglichen Unix-Version, und ich würde erwarten, dass es in jeder Unix-Variante gleich ist, und ich wäre überrascht, wenn es eine Unix-Variante gäbe das verhielt sich anders.
quelle
rm -r
undmkdir
undrmdir
nicht (das Erstellen (mitmknod(2)
)) und Entfernen (mit Gleichemunlink(2)
für andere Dateitypen) Verzeichnisse war und das Verknüpfen und Aufheben der Verknüpfung von "." - und ".." -Einträgen in ihnen wurde im Benutzerraum durchgeführt, die Zugriffskontrolle wurde auch im Benutzerraum von den Dienstprogrammenmkdir
und durchgeführtrmdir
).readdir
die Kernel-Listeneinträge zu haben)? Faszinierend.Ich habe versucht zu reproduzieren, was Sie beschreiben, und bin gelaufen
strace rm -rf ./nonempty
. Was dies offenbart, ist Folgendes:und laut
unlinkat
Handbuch (was unter Linux dasselbe ist wieunlink(2)
, Hervorhebung von mir hinzugefügt):Da das übergeordnete Verzeichnis
nonempty
keineuser
x-Berechtigung (Suche) erteilt, ist es sinnvoll, basierend auf derEACCES
Beschreibung,subdir
die nicht entfernt werden kann.quelle
foo
undbar
, aber nichtsome
in/foo/bar/some
. Sie können dies versuchen :mkdir d; chmod 0 d; rmdir d
, es sollte in Ordnung funktionieren. Natürlichnon-empty-subdir
passiert dies ohne Suchberechtigung , aber ohne Schreibberechtigung würde es trotzdem passieren. Außerdem: Suchberechtigung ist dasx
Bit, es ist nicht dasselbe wie Leseberechtigungnon-empty-subdir
lesbaren, aber nicht beschreibbaren Test getestet haben . Derrm
Befehl des OP konnte nicht einmal herausfinden, dass sich darin ein Inhalt befindetsubdir
, da sie keine Leseberechtigung haben (beachten Sie, dass siesudo
den Inhalt aufgelistet haben). Siehe die aktualisierte Antwort von Stéphane Chazelas.non-empty
undsubdir
700 Berechtigungen festgelegt, genau wie im Beispiel von OP, undchown
beide so bearbeitet , dass sie einem anderen Benutzer und seiner Gruppe gehören.rm -rf ./nonempty
konnte man dann einenunlinkat(4, "subdir", AT_REMOVEDIR)
Systemaufruf tätigen , wenn er nicht einmal lesen konnte./nonempty
, um den Namen zu findensubdir
?