在以下情况下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
其中存在两个子目录(不属于我),我将其列为:
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
这两个子目录的区别在于非空non-empty-subdir
包含一个文件夹。
rm -rf
我的问题是尝试删除子目录是否是设计使我得到的结果:
$ 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
似乎允许对目录具有写权限的用户删除文件的条目或其他用户的空子目录,但不能删除非空子目录。
这个问题的理想答案将提供以下信息:
- 确认概述的行为可以在其他机器上重现(而不仅仅是我搞砸的盒子的怪癖)
- 解释该行为的理由(例如,有用例吗?)
- 系统之间是否存在差异的概述(BSD,Linux ....)
更新:关于 Ipor Sircer 的评论,我确实重新测试了场景,没有任何 ACL 功能,它是相同的。因此,我修改了问题以+
从列表中删除 es,以免产生行为可能与 ACL 相关的想法。
rmdir()
如果目录为空,则只能删除目录(使用系统调用)。rm -r dir
删除目录和其中的所有文件,从目录树的叶子开始,一直到根 (dir
)。要删除文件(
rmdir()
用于目录和unlink()
其他类型的文件或*at()
变体),重要的不是文件本身的权限,而是您要从中删除文件的目录的权限(注意t
权限中的位,例如对于/tmp
,增加了进一步的复杂性)。毕竟,您并没有真正删除文件,而是从目录中取消链接(当它是您要删除的最后一个链接时,文件最终会被删除),也就是说,您是修改目录,因此您需要修改(写入)该目录的权限。
不能删除的原因
non-empty-dir
是不能subdir
先解除链接,因为你没有修改的权限non-empty-dir
。您有权non-empty-dir
从主目录取消链接,因为您对该主目录具有写入/修改权限,但您不能删除非空目录。在您的情况下,正如@PeterCordes 在评论中指出的那样,
rmdir()
系统调用失败并出现ENOTEMPTY
(目录非空)错误代码,但由于您没有对该目录的读取权限,rm
因此甚至无法找出哪些文件和目录(包括subdir
)它需要从它取消链接才能清空它(如果它知道它可以取消链接它们,因为它没有写权限)。您还可能遇到
rm
可以删除目录的情况,前提是它可以找出其中的文件,例如只写目录:不过,我可以删除它,因为我碰巧知道它只包含一个
file
文件:另请注意,使用现代 Unices,您可以重命名它
non-empty-dir
,但在 Linux 或 FreeBSD(但不是 Solaris)上,即使您还拥有对该目录的写权限,也不要将其移动到不同的目录,如(我认为对于 Linux ,正如相关代码的注释所建议的那样)这样做将涉及修改non-empty-dir
(其中的..
条目将指向不同的目录)。有人可能会争辩说,删除 your
empty-dir
还涉及删除其中的..
and.
条目,因此对其进行修改,但系统仍然允许您这样做。忽略通过 ACL 的潜在变化,我可以确认我的系统的这种行为(没有 ACL)。
观察到的行为是两个原则的逻辑结果:
1) 目录的权限决定了谁可以更改目录,即删除目录中的条目。该目录中条目的权限在此不起作用。
2) 删除文件可能需要删除和清理相关信息,即 inode、块分配列表等。这就是为什么你不能在不清理它包含的所有文件的情况下删除非空子目录,因为否则它包含的文件会变得无法访问,但相关信息不会被清理。
所以你可以 remove
empty-subdir
,因为你有权写入它所在的目录。你不能 removenon-empty-subdir
,因为你没有权限先清理这个子目录中包含的文件。这真的没有理由或用例。可以将子目录的递归清理构建到内核中,但最初的 Unix 使一切都保持简单,如果可以使用用户空间实用程序来实现递归清理,它就太复杂了。
我无法提供不同风格之间的全面概述,但这是原始 Unix 中的行为,我希望它在每种风格的 Unix 中都是相同的,如果有一种风格的 Unix,我会感到惊讶表现不同。
我试图重现您所描述的内容,然后运行
strace rm -rf ./nonempty
. 这揭示了以下内容:并根据
unlinkat
手册(在Linux上与我添加的重点相同unlink(2)
):由于父目录 ,
nonempty
不授予x (搜索)权限,因此基于无法删除的描述是user
有意义的。EACCES
subdir