为什么“rm -r”无法删除此文件夹?

Joh*_*ohn 14 linux permissions rm

我有一个文件夹-wx的权限称为folder1和里面的另一个文件夹名为folder2rwx权限。

我尝试folder1使用以下命令删除:

rm -r folder1
Run Code Online (Sandbox Code Playgroud)

但我收到以下错误:

rm: cannot remove 'folder1': Permission denied
Run Code Online (Sandbox Code Playgroud)

我认为我收到此错误的原因是因为rm程序需要首先获取内容folder1(获取其中的文件和文件夹的名称folder1)才能删除该内容(因为您无法删除文件或我认为不知道其名称的文件夹),然后rm程序可以folder1自行删除。

但是既然folder1没有read权限,那么rm程序就不能得到它的内容,也就不能删除它的内容,既然不能删除它的内容,也就不能删除它。

我对么?

use*_*709 19

我认为您的分析是正确的:您不能删除该目录,因为它不是空的,您不能清空它,因为您看不到它的内容。

我只是试了一下:

$ mkdir -p folder1/folder2
$ chmod -r folder1
$ rm -rf folder1
rm: cannot remove 'folder1': Permission denied
$ rmdir folder1/folder2
$ rm -rf folder1
$ 
Run Code Online (Sandbox Code Playgroud)

当我写“你”时,我的意思是你可以运行的任何程序。您的rm -r命令首先看到这folder1是一个目录,因此它尝试发现其内容以清空它,但由于缺少读取权限而失败,然后它尝试删除它但由于它非空而失败。“拒绝许可”具有误导性;我认为“目录不为空”(如rmdir报告)会更合适。)

  • 在这种情况下,它无法报告“目录不为空”,因为它不知道它是否为空。尝试删除您没有读取权限的 _empty_ 目录时,您仍然会遇到相同的错误。(另外,请忽略我之前的评论,我没有思考上限)。 (4认同)
  • 您的测试显示了我们系统之间的有趣差异。当它为空时尝试“rm -r folder1”时,我收到“权限被拒绝”。我使用的是 OpenBSD,而不是 Linux。 (2认同)

小智 7

要进行删除,系统必须能够读取内容并识别必须删除的内容。

我试过模拟你正在尝试的东西:

[vagrant@desktop1 ~]$ 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)
[vagrant@desktop1 ~]$ ls -lh
total 0
d-wx-wx-wx. 3 vagrant vagrant 21 Feb 24 10:40 folder1
[vagrant@desktop1 ~]$ 
Run Code Online (Sandbox Code Playgroud)

如果我们尝试在没有读取权限的情况下删除它会失败:

[vagrant@desktop1 ~]$ rm -r folder1/
rm: cannot remove 'folder1/': Permission denied
[vagrant@desktop1 ~]$ sudo chmod +r folder1/
[vagrant@desktop1 ~]$ rm -r folder1/
[vagrant@desktop1 ~]$ 
Run Code Online (Sandbox Code Playgroud)

在两次尝试的 strace 中,不同之处在于无法读取目录内容(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
Run Code Online (Sandbox Code Playgroud)

具有读取权限:

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
Run Code Online (Sandbox Code Playgroud)

总而言之,即使您拥有一个目录并且它具有可执行位,您仍然需要读取权限,以便您可以查看其内容并删除该文件夹。但是对于文件来说并不相同。