在以下情况下 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
Run Code Online (Sandbox Code Playgroud)
其中存在两个子目录(不属于我),我将其列为:
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
Run Code Online (Sandbox Code Playgroud)
两个子目录之间的区别在于非空目录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
Run Code Online (Sandbox Code Playgroud)
似乎允许对目录具有写权限的用户删除文件条目或其他用户的空子目录,但不能删除非空子目录。
这个问题的理想答案将提供以下信息:
更新:关于 Ipor Sircer 的评论,我确实重新测试了场景,没有任何 ACL 功能,它是相同的。因此,我修改了问题以+从列表中删除es,以免产生这种行为可能与 ACL 相关的想法。
Sté*_*las 14
rmdir()如果目录为空,则只能删除目录(使用系统调用)。
rm -r dir删除目录和其中的所有文件,从目录树的叶子开始,一直到根 ( dir)。
要删除文件(rmdir()对于目录和unlink()其他类型的文件或*at()变体),重要的不是文件本身的权限,而是要从中删除文件的目录t的权限(注意权限中的一点,例如为/tmp,增加了进一步的复杂性)。
首先,您并没有真正删除文件,而是从目录中取消链接(并且当它是您要删除的最后一个链接时,该文件最终会因此被删除),也就是说,您是修改目录,因此您需要修改(写入)该目录的权限。
您无法删除的原因non-empty-dir是您无法先取消链接subdir,因为您无权修改non-empty-dir. 您有权取消non-empty-dir与您的主目录的链接,因为您拥有对该主目录的写入/修改权限,但您不能删除非空目录。
在您的情况下,正如@PeterCordes 在评论中所指出的,rmdir()系统调用失败并显示ENOTEMPTY(Directory not empty) 错误代码,但由于您没有对该目录的读取权限,rm甚至无法找出哪些文件和目录(包括subdir)它需要与它取消链接才能清空它(如果它知道,它不会取消链接,因为它没有写权限)。
您还可以进入rm 可以删除目录的情况,前提是它可以找出其中的文件,例如在只写目录的情况下:
$ 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
Run Code Online (Sandbox Code Playgroud)
不过,我可以删除它,因为我碰巧知道它只包含一个file文件:
$ rm dir/file
$ rmdir dir
$
Run Code Online (Sandbox Code Playgroud)
另请注意,使用现代 Unices,您可以重命名它non-empty-dir,但在 Linux 或 FreeBSD(但不是 Solaris)上,即使您对该目录也有写权限,也不要将其移动到其他目录,如(我认为对于 Linux ,正如相关代码的评论所建议的那样)这样做将涉及修改non-empty-dir(其中的..条目将指向不同的目录)。
有人可能会争辩说,删除您的empty-dir还包括删除其中的..和.条目,因此对其进行修改,但系统仍然允许您这样做。
忽略通过 ACL 进行的潜在更改,我可以为我的系统(没有 ACL)确认此行为。
观察到的行为是两个原则的逻辑结果:
1) 目录的权限决定了谁可以更改目录,即删除目录中的条目。该目录中条目的权限在此不起作用。
2) 删除文件可能需要删除和清理相关信息,即 inode、块分配列表等。这就是为什么你不能在没有清理它包含的所有文件的情况下删除非空子目录,因为否则它包含的文件会变得无法访问,但相关信息不会被清理。
因此,您可以删除empty-subdir,因为您有权写入它所在的目录。您不能删除non-empty-subdir,因为您无权首先清除此子目录中包含的文件。
这真的没有理由或用例。可以将子目录的递归清理构建到内核中,但是最初的 Unix 使一切变得简单,如果可以使用用户空间实用程序来实现递归清理,则它就太复杂了。
我无法提供不同风格之间的全面概述,但这是原始 Unix 中的行为,我希望它在每种 Unix 风格中都相同,如果有 Unix 风格,我会感到惊讶表现不同。
| 归档时间: |
|
| 查看次数: |
609 次 |
| 最近记录: |