
In der folgenden Situationls -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 (die nicht mein Eigentum sind) existieren, die ich wie folgt aufliste:
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 non-empty-subdir
einen Ordner enthält.
Meine Frage ist nun, ob es so beabsichtigt ist, dass rm -rf
ich beim Versuch, die Unterverzeichnisse zu entfernen, folgende 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 Schreibberechtigung für ein Verzeichnis einen Eintrag für eine Datei oder ein leeres Unterverzeichnis eines anderen Benutzers entfernen darf, aber nicht einennicht leerUnterverzeichnis.
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 eine Macke meiner kaputten Box ist)
- eine Begründung für dieses Verhalten (z. B. gibt es Anwendungsfälle?)
- eine Übersicht, ob es Unterschiede zwischen Systemen (BSD, Linux...) gibt
Aktualisieren: In Bezug auf den Kommentar von Ipor Sircer habe ich das Szenario erneut getestet, ohne jegliche ACL-Funktionen, und es ist dasselbe. Ich habe die Frage daher geändert, um die +
es aus den Auflistungen zu entfernen, damit nicht der Eindruck entsteht, dass das Verhalten mit ACLs zusammenhängen könnte.
Antwort1
Man kann ein Verzeichnis (mit dem rmdir()
Systemaufruf) nur entfernen, wenn es leer ist.
rm -r dir
entfernt das Verzeichnis und alle darin enthaltenen Dateien, beginnend mit den Blättern des Verzeichnisbaums und sich bis zur Wurzel vorarbeitend ( dir
).
Um eine Datei zu entfernen (mit rmdir()
für Verzeichnisse und unlink()
für andere Dateitypen oder *at()
Varianten), kommt es nicht auf die Berechtigung der Datei selbst an, sondern auf die des Verzeichnisses, aus dem Sie die Datei entfernen (achten Sie darauf, dass der t
Teil in den Berechtigungsangaben, wie z. B. für /tmp
, das Ganze noch komplizierter macht).
Vor allem entfernen Sie nicht wirklich dieDatei, Sie trennen die Verknüpfung mit einem Verzeichnis (und wenn Sie die letzte Verknüpfung entfernen, wird die Datei infolgedessen gelöscht), das heißt, Sie ändern das Verzeichnis, also müssen SieÄndern(Schreib-)Berechtigungen für dieses Verzeichnis.
Der Grund, warum Sie es nicht entfernen können, ist, dass Sie die Verknüpfung nicht zuerst non-empty-dir
aufheben können , da Sie nicht das Recht haben, es zu ändern . Sie hätten das Recht, die Verknüpfung zu Ihrem Home-Verzeichnis aufzuheben, da Sie dort Schreib-/Änderungsrechte haben. Sie können jedoch kein Verzeichnis entfernen, das nicht leer ist.subdir
non-empty-dir
non-empty-dir
In Ihrem Fall, wie von @PeterCordes in den Kommentaren angemerkt, schlägt der rmdir()
Systemaufruf mit einem ENOTEMPTY
(Verzeichnis nicht leer) Fehlercode fehl, aber da Sie nicht habenlesenhat keine Schreibberechtigung für das Verzeichnis, rm
kann aber nicht einmal herausfinden, bei welchen Dateien und Verzeichnissen (einschließlich subdir
) die Verknüpfung aufgehoben werden müsste, um das Verzeichnis leeren zu können (nicht, dass es die Verknüpfungen aufheben könnte, wenn es das wüsste, da es keine Schreibberechtigung hat).
Sie können auch in Situationen geraten, in denenrm
könnteEntfernen Sie ein Verzeichnis, wenn nur herausgefunden werden könnte, welche Dateien sich darin befinden, wie im Fall eines schreibgeschützten Verzeichnisses:
$ mkdir dir
$ touch dir/file
$ chmod a=,u=wx dir
$ ls -ld dir
d-wx------ 2 me me 4096 Nov 30 19:43 dir/
$ rm -rf dir
rm: cannot remove 'dir': Permission denied
Ich kann es trotzdem entfernen, da ich zufällig weiß, dass es nur eine file
Datei enthält:
$ rm dir/file
$ rmdir dir
$
Beachten Sie auch, dass Sie bei modernen Unix-Systemen diesen Namen umbenennen können non-empty-dir
, bei manchen jedoch, wie Linux oder FreeBSD (aber nicht Solaris),nichtverschieben Sie es in ein anderes Verzeichnis, auch wenn Sie auch Schreibberechtigung für dieses Verzeichnis hatten, wie (glaube ich und für Linux, wie vorgeschlagen vonder Kommentar zum jeweiligen Code) Dies würde eine Änderung erfordern non-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 darin enthaltenen ..
und Einträge und somit das Ändern der Datei beinhaltet, aber das System lässt dies dennoch zu..
Antwort2
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, also Einträge im Verzeichnis löschen darf. Die Rechte der Einträge in diesem Verzeichnis spielen dabei keine Rolle.
2) Das Entfernen einer Datei erfordert möglicherweise das Entfernen und Bereinigen zugehöriger Informationen, d. h. Inodes, Blockzuordnungslisten usw. Aus diesem Grund können Sie ein nicht leeres Unterverzeichnis nicht entfernen, ohne alle darin enthaltenen Dateien bereinigt zu haben, da andernfalls die darin enthaltenen Dateien unzugänglich würden, die zugehörigen Informationen jedoch nicht bereinigt worden wären.
Sie können es also entfernen empty-subdir
, da Sie über Schreibrechte für das Verzeichnis verfügen, in dem es sich befindet. Sie können es nicht entfernen non-empty-subdir
, da Sie nicht über die Rechte verfügen, zuerst die in diesem Unterverzeichnis enthaltenen Dateien zu bereinigen.
Dafür gibt es wirklich keinen Grund oder Anwendungsfall. Man hätte die rekursive Bereinigung eines Unterverzeichnisses in den Kernel einbauen können, aber das ursprüngliche Unix hielt alles einfach, und die rekursive Bereinigung wäre zu kompliziert gewesen, wenn sie mit einem Dienstprogramm im Benutzerbereich erreicht werden kann.
Ich kann keinen umfassenden Überblick über die verschiedenen Varianten geben, aber dies war das Verhalten des ursprünglichen Unix und ich würde erwarten, dass es bei allen Unix-Varianten gleich ist. Es würde mich überraschen, wenn es eine Unix-Variante gäbe, die sich anders verhält.
Antwort3
Ich habe versucht, Ihre Beschreibung nachzubilden und habe ausgeführt strace rm -rf ./nonempty
. Dabei wurde Folgendes festgestellt:
unlinkat(4, "subdir", AT_REMOVEDIR) = -1 EACCES (Permission denied)
und laut unlinkat
Handbuch (das unter Linux dasselbe ist wie unlink(2)
, Hervorhebung von mir):
EACCES Der Schreibzugriff auf das Verzeichnis mit dem Pfadnamen ist für die effektive UID des Prozesses nicht zulässig, oder eines der Verzeichnisse im Pfadnamen hat keine Suchberechtigung zugelassen. (Siehe auch path_resolution(7).)
Da das übergeordnete Verzeichnis nonempty
keine user
Berechtigung „x“ (Suchen) gewährt, ist es aufgrund der EACCES
Beschreibung sinnvoll, dass subdir
es nicht entfernt werden kann.