为什么Linux不允许删除只读目录?

为什么Linux不允许删除只读目录?

我是 Linux 新手。当我将文件设置为只读时,我仍然可以删除该文件。我在网上读到删除文件取决于它所在文件夹的权限。

为了清楚起见,假设我有一个目录 test(具有所有权限),其中有一个只读文件“abc.txt”。即使这个文件是只读的,我也可以轻松删除它。

现在考虑这样的情况:我有一个正在测试的名为“sub”的子目录。该目录是只读的。当我想删除这个子目录时,它会抛出一个错误,指出无法删除这个目录。

在 Linux 中,目录也被视为文件。但只读文件与只读目录的行为有所不同。

这是什么原因呢?

答案1

因为 Unix 就是这样定义的,并且 POSIX 需要这种行为。 Linux 试图兼容 Unix 和 POSIX。

您可能对什么有一些误解文件是(注意,Unix 和 Windows 上的并不完全相同)。顺便说一句,它们对很多人来说都很重要系统调用(列于系统调用(2)),有几个系统调用给出文件描述符从文件路径(另请参见路径分辨率(7))。与其他一些操作系统相比,文件(在 Linux 或 Unix 或 POSIX 系统上)不仅具有姓名(或小路):有些文件没有名称,有些文件有多个名称;事实上,大多数文件都有一个名称。

请记住,文件是一个抽象为...提供用户空间(和应用-包括公用事业程序-运行于流程)由操作系统内核。系统调用是程序(以及运行它们的进程)与内核交互的唯一方式。

您的磁盘不知道文件(但您的操作系统知道)。磁盘仅包含字节块。您的操作系统将它们理解为文件

文件(在 Unix 和 Linux 上)是一个索引节点。也可以看看索引节点(7)。索引节点包含有关该文件的元数据(您可以使用以下命令进行查询)统计数据(2)fstat ...) - 包括类型、创建时间、权限、所有权、大小等 - 并包含(或更常见的是指向)文件数据(字节序列)。

但删除只读目录不会有任何问题。

A目录是一种特殊类型的文件(除了普通文件和目录之外还有其他类型的文件,例如先进先出(7)-s,符号链接(7)-s 等)。它包含一个将字符串映射到 inode 的字典。这种情况的发生方式因每种文件系统类型而异。使用打开目录(3)(以及稍后closedir)和读取目录(3)阅读它。

....它所在文件夹的权限...

误解。文件夹在 Linux 上不存在(它们是图形用户界面人工制品有时由您显示的桌面环境),您可能正在谈论目录。文件系统包含各种类型的文件(包括目录和符号链接)。

给定的 inode 可以出现在一些目录(你可能会说一个文件可以有一些路径,那么它们都具有相同的“权力”和相似的“角色”)。使用链接(2)系统调用 - 也许通过ln(1)命令 - 用于向文件添加一些附加路径。使用取消链接(2)用于删除文件路径的系统调用。在某些情况下,索引节点可以存在而不出现在任何目录中。一个常见的情况(用于实现临时文件)是当您创建文件时 -eg 使用创造(2)open然后unlink(或删除(3))紧接着该文件(例如在同一进程中,但可能不是)。

当某个 inode 变得无法访问时(因为没有打开的文件描述符,并且在某些目录中不再提及它),内核会删除该 inode(以及与其相关的数据块)。

当您“删除”文件时(例如使用房间(1)实用程序),/bin/rm程序(以及运行该命令的进程)只是使用unlink(并且您正在写入包含名称和 inode 之间的某些映射的目录)。如果没有更多“指向”该索引节点,那么它确实会被删除。由于内核正在写入目录,因此它要求您的进程具有写入权限。也可以看看凭证(7)

需要一个目录目录(2)待制作,并且目录(2)被删除(从其父级):如果您使用取消链接(2)要删除它,将会失败EISDIR。但目录(2)要求目录为空(因为内核要求文件层次结构是有向无环图, 和循环引用被某种形式禁止引用计数)。mkdir和系统调用都处理目录的rmdir魔法  .和条目。..

但删除只读目录不会有任何问题。为什么这个东西不依赖父目录呢?

一般情况下确实如此(但是粘性位目录上有一些特定的含义)。

关于编辑的问题

在您编辑的问题中,您声称(不正确,或者缺少一些重要细节):

现在考虑这样的情况:我有一个名为subunder 的子目录test。该目录是只读的。当我想删除这个子目录时,它会抛出一个错误,指出无法删除这个目录。

我无法重现您的主张(请提供一些MCVE)。为了便于阅读,我正在考虑目录testdirsubdir不是你的名字(但这不会改变任何东西;但是你的名字test很容易混淆测试(1)

 % /bin/mkdir testdir
 % /bin/mkdir testdir/subdir
 % /bin/ls -la testdir
total 12
drwxr-xr-x 3 basile basile 4096 Apr 24 13:09 .
drwxr-xr-x 6 basile basile 4096 Apr 24 13:08 ..
drwxr-xr-x 2 basile basile 4096 Apr 24 13:09 subdir
 % /bin/chmod a-w testdir/subdir
 % /bin/ls -la testdir          
total 12
drwxr-xr-x 3 basile basile 4096 Apr 24 13:09 .
drwxr-xr-x 6 basile basile 4096 Apr 24 13:08 ..
dr-xr-xr-x 2 basile basile 4096 Apr 24 13:09 subdir
 % /bin/rmdir testdir/subdir  
 % /bin/ls -la testdir      
total 8
drwxr-xr-x 2 basile basile 4096 Apr 24 13:14 .
drwxr-xr-x 6 basile basile 4096 Apr 24 13:08 ..

请记住目录(1)(它使用目录(2)系统调用)要求删除的目录为空,并且某些文件(名称以点开头)可能被您的 shell 或ls.列出已删除目录的所有文件ls -a


你可能会读到操作系统:三个简单的部分

答案2

不可以,如果目录的父目录是只读的,则无法删除该目录。自己尝试一下:

$ cd /tmp
$ mkdir -p /tmp/readonly1/readonly2
$ chmod 555 /tmp/readonly1/readonly2 /tmp/readonly1   # dr-xr-xr-x
$ rmdir /tmp/readonly1/readonly2
rmdir: failed to remove '/tmp/readonly1/readonly2': Permission denied

强行删除也无济于事:

$ rm -rf /tmp/readonly1/readonly2
rm: cannot remove '/tmp/readonly1/readonly2': Permission denied
$ rm -rf /tmp/readonly1
rm: cannot remove '/tmp/readonly1/readonly2': Permission denied
$ chmod 755 /tmp/readonly1/readonly2  # drwxr-xr-x
$ rm -rf /tmp/readonly1
rm: cannot remove '/tmp/readonly1/readonly2': Permission denied

但是一旦你使readonly1目录可写,你就可以删除它的子目录readonly2

$ chmod 555 /tmp/readonly1/readonly2  # dr-xr-xr-x
$ chmod 755 /tmp/readonly1            # drwxr-xr-x
$ rmdir /tmp/readonly1/readonly2
$ rmdir /tmp/readonly1        #... or just rm -rf /tmp/readonly1 all at once
$ ls /tmp/readonly1
ls: cannot access '/tmp/readonly1': No such file or directory

相关内容