it-swarm.com.de

Warum kann "rm -r" diesen Ordner nicht löschen?

Ich habe einen Ordner mit -wx - Berechtigungen namens folder1 Und einen anderen Ordner namens folder2 Mit rwx - Berechtigungen.

Ich habe versucht, folder1 Mit diesem Befehl zu löschen:

rm -r folder1

Aber ich habe folgenden Fehler bekommen:

rm: cannot remove 'folder1': Permission denied

Der Grund, warum ich glaube, dass ich diesen Fehler erhalten habe, ist, dass das Programm rm zuerst den Inhalt von folder1 Abrufen muss (die Namen der Dateien und Ordner in folder1 Abrufen). Um diesen Inhalt löschen zu können (weil Sie eine Datei oder einen Ordner nicht löschen können, ohne den Namen zu kennen, denke ich), kann das Programm rmfolder1 selbst löschen.

Da folder1 Nicht über die Berechtigung read verfügt, kann das Programm rm seinen Inhalt nicht abrufen und daher seinen Inhalt nicht löschen kann seinen Inhalt nicht löschen, dann kann er ihn nicht löschen.

Hab ich recht?

12
John

Ich denke, Ihre Analyse ist korrekt: Sie können das Verzeichnis nicht löschen, da es nicht leer ist, und Sie können es nicht leeren, da Sie seinen Inhalt nicht sehen können.

Ich habe es gerade versucht:

$ mkdir -p folder1/folder2
$ chmod -r folder1
$ rm -rf folder1
rm: cannot remove 'folder1': Permission denied
$ rmdir folder1/folder2
$ rm -rf folder1
$ 

Als ich "Sie" schrieb, meinte ich jedes Programm, das Sie ausführen dürfen. Ihre rm -r Befehl sieht zuerst, dass folder1 ist ein Verzeichnis, daher versucht es, seinen Inhalt zu ermitteln, um es zu leeren, schlägt jedoch fehl, weil die Leseberechtigung fehlt. Dann versucht es, es zu löschen, schlägt jedoch fehl, weil es nicht leer ist. Die "Erlaubnis verweigert" ist irreführend; Ich denke, "Verzeichnis nicht leer" (wie rmdir Berichte) wäre angemessener.)

19
user2233709

Damit das Löschen erfolgen kann, muss das System in der Lage sein, den Inhalt zu lesen und zu identifizieren, was gelöscht werden muss.

Ich habe versucht zu simulieren, was Sie versuchen:

[[email protected] ~]$ Sudo rm -rf folder1/ && mkdir -pv folder1/folder2 && Sudo chmod 333 -v folder1/ && Sudo chmod 777 -v folder1/folder2
mkdir: created directory 'folder1'
mkdir: created directory 'folder1/folder2'
mode of 'folder1/' changed from 0775 (rwxrwxr-x) to 0333 (-wx-wx-wx)
mode of 'folder1/folder2' changed from 0775 (rwxrwxr-x) to 0777 (rwxrwxrwx)
[[email protected] ~]$ ls -lh
total 0
d-wx-wx-wx. 3 vagrant vagrant 21 Feb 24 10:40 folder1
[[email protected] ~]$ 

Wenn wir versuchen, ohne Leseberechtigung zu löschen, schlägt dies fehl:

[[email protected] ~]$ rm -r folder1/
rm: cannot remove 'folder1/': Permission denied
[[email protected] ~]$ Sudo chmod +r folder1/
[[email protected] ~]$ rm -r folder1/
[[email protected] ~]$ 

Bei den beiden Versuchen besteht der Unterschied darin, dass der Verzeichnisinhalt nicht gelesen werden kann (getdents):

newfstatat(AT_FDCWD, "folder1/", {st_mode=S_IFDIR|0333, st_size=21, ...}, AT_SYMLINK_NOFOLLOW) = 0
openat(AT_FDCWD, "folder1/", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_DIRECTORY|O_NOFOLLOW) = -1 EACCES (Permission denied)
geteuid()                               = 1000
newfstatat(AT_FDCWD, "folder1/", {st_mode=S_IFDIR|0333, st_size=21, ...}, AT_SYMLINK_NOFOLLOW) = 0
faccessat(AT_FDCWD, "folder1/", W_OK)   = 0
openat(AT_FDCWD, "folder1/", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_DIRECTORY|O_NOFOLLOW) = -1 EACCES (Permission denied)
newfstatat(AT_FDCWD, "folder1/", {st_mode=S_IFDIR|0333, st_size=21, ...}, AT_SYMLINK_NOFOLLOW) = 0

Mit Leseberechtigungen:

newfstatat(AT_FDCWD, "folder1/", {st_mode=S_IFDIR|0777, st_size=21, ...}, AT_SYMLINK_NOFOLLOW) = 0
openat(AT_FDCWD, "folder1/", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_DIRECTORY|O_NOFOLLOW) = 3
fstat(3, {st_mode=S_IFDIR|0777, st_size=21, ...}) = 0
fcntl(3, F_GETFL)                       = 0x38800 (flags O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_NOFOLLOW)
fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
getdents(3, /* 3 entries */, 32768)     = 80
close(3)                                = 0
geteuid()                               = 1000

Selbst wenn Sie ein Verzeichnis besitzen und es über das ausführbare Bit verfügt, benötigen Sie weiterhin Leseberechtigungen, damit Sie dessen Inhalt sehen und den Ordner löschen können. Bei einer Datei ist dies jedoch nicht dasselbe.

7
ttaran7

Nun, ich habe nicht genug Ruf, um die Antwort von ttaran7 zu kommentieren, also sieht es so aus, als müsste es eine Antwort sein. Mein Up-Vote ist aufgrund des geringen Ansehens auch nicht öffentlich sichtbar. Ich habe diese Antwort dafür gewählt, dass sie tatsächlich einen Systemaufruf-Trace enthält und nicht nur Spekulationen.

m die Frage des OP zu beantworten: Ja, Ihre Argumentation war richtig: Sie werden blockiert, wenn Sie das Verzeichnis nicht lesen können.

Ich habe eine ähnliche Ablaufverfolgung durchgeführt wie sie (ttaran7), weil ich die gleiche Argumentation vermutete: Der Aufruf von rm würde fehlschlagen, wenn das Verzeichnis nicht gelesen würde, und das wäre das Ende davon, keine Chance, sich darüber zu beschweren Das Verzeichnis ist leer. Bei einem zweiten Blick auf die von mir aufgenommene Ablaufverfolgung stellte ich fest, dass ein Systemaufruf ausgeführt wurde, um zu versuchen, die Verknüpfung des angegebenen Dateinamens trotzdem aufzuheben:

newfstatat(AT_FDCWD, "folder1", {st_mode=S_IFDIR|0311, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0
openat(AT_FDCWD, "folder1", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW|O_DIRECTORY) = -1 EACCES (Permission denied)
openat(AT_FDCWD, "folder1", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW|O_CLOEXEC|O_DIRECTORY) = -1 EACCES (Permission denied)
unlinkat(AT_FDCWD, "folder1", AT_REMOVEDIR) = -1 ENOTEMPTY (Directory not empty)
openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=2995, ...}) = 0
read(3, "# Locale name alias data base.\n#"..., 4096) = 2995
read(3, "", 4096)                       = 0
close(3)                                = 0
openat(AT_FDCWD, "/usr/share/locale/en_AU/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale-langpack/en_AU/LC_MESSAGES/coreutils.mo", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=45256, ...}) = 0
mmap(NULL, 45256, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f8db25ca000
close(3)                                = 0
openat(AT_FDCWD, "/usr/share/locale- langpack/en/LC_MESSAGES/coreutils.mo", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=578, ...}) = 0
mmap(NULL, 578, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f8db25c9000
close(3)                                = 0
write(2, "rm: ", 4rm: )                     = 4
write(2, "cannot remove 'folder1'", 23cannot remove 'folder1') = 23
openat(AT_FDCWD, "/usr/share/locale/en_AU/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale-langpack/en_AU/LC_MESSAGES/libc.mo", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=2893, ...}) = 0
mmap(NULL, 2893, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f8db25c8000
close(3)                                = 0
openat(AT_FDCWD, "/usr/share/locale-langpack/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
write(2, ": Permission denied", 19: Permission denied)     = 19
write(2, "\n", 1
lseek(0, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
close(0)                                = 0
close(1)                                = 0
close(2)                                = 0
exitgroup(1)

Schauen Sie sich die 4. Zeile an: unlinkat... was fehlschlägt, weil das Verzeichnis NICHT leer ist. Nun, das ist es, was ich als unerwartetes Verhalten betrachten würde, die Tatsache, dass es versucht, das Verzeichnis überhaupt zu löschen, obwohl es keine Leseberechtigungen hat.

0
ojklan