硬链接数变为0时是否删除目录?


10

硬链接数变为0时是否删除目录?

由于,目录的硬链接数始终至少为2 .。当rm -r是目录时,是否将硬链接的数量从2减少到0,而不是2,而不是1?

目录的硬链接数量可以为1吗?

谢谢。

Answers:


9

首先,并非所有文件系统都使用...作为硬链接。这在gnu查找手册中有记录。在我的其余回答中,我将忽略那些文件系统,因为它们不是为unix设计的,只是使事情复杂而没有增加清晰度。由于相同的原因,我还将忽略根目录和安装点。

链接到一个目录的数量超过两个,因为从来没有少...。子目录的数量等于链接数减去两个。正因为如此,你不能链接或解除目录,因此rm -rstat删除和使用前的文件rmdir,而不是unlink在目录上。这两个系统调用在内核中使用完全不同的代码路径。


谢谢。目录具有硬链接..,仅当它具有子目录时,对吗?因此..,目录并不总是存在吗?
蒂姆(Tim)

..存在于每个该目录一个子目录。这就是所有,但/也有一个,所以所有目录。
hildred,2015年

1
(1)如果目录没有子目录,则目录本身没有硬链接..。什么是目录的硬链接?带有路径名的文件,以及.?(2)为什么忽略安装点?
蒂姆(Tim)

如果目录是子目录。该条目..将指向父级。在特殊情况下,根目录链接指向自身。这使cd ..\..无论您身在何处,类似的命令都可以按预期工作。您可以使用stat命令进行测试。
BillThor 2015年

1
您是正确的,链接数绝不小于2,但这不是因为..。这是因为,.父目录中的名称指向该目录。唯一的例外是根,它没有父级。但是它已经..指向自己了,所以它的链接数也=
2。– Barmar

11

在常规设计的UNIX文件系统上,其引用计数(例如,硬链接计数打开的文件句柄数之 *)达到0的任何文件都将被删除。然而,在现代UNIX系统中,rmdir系统调用删除在一次操作中的空目录,而不是删除.,并..一个接一个。

但是,在历史悠久的UNIX系统中,此系统调用不存在。相反,该rmdir 命令是setuid程序(可在此处找到源代码),该程序检查目录是否为空(特殊条目除外),然后依次删除..和和.,然后删除目录本身,所有操作都使用unlink系统调用,仅root用户可以在目录上使用(因此,为什么将命令设置为setuid)。因此,在这些系统上,目录的链接计数在.删除之后但在从父目录中删除目录之前暂时为1 ,然后为0。

rm顺便说一句,该命令甚至阻止root用户删除目录。并且在清空目录内容后rm -r会调出rmdir命令以删除目录。

在这些历史系统上,滥用unlink从以root身份运行,使用rmdir或进入竞争状态的程序的调用mv,或在已删除当前目录的进程中创建文件(现代系统禁止这样做),可能会导致文件或目录晃晃硬链接计数大于0但在目录树中不存在。该状况已由检测到dcheck,但仍是检查的条件之一,fsck因为在大多数文件系统上它仍然物理上可行。


顺便说一句,不需要文件系统将目录(包括...)实现为具有硬链接的普通文件。在这些文件系统上,目录的硬链接计数将始终报告为0(但当然,其在父目录中的存在表示“引用计数”为1)。


未指定已删除目录的行为(例如,当已打开目录或将其作为当前目录的进程检查时)以及目录“链接计数”的确切含义。例如,在Mac OS X上,即使没有真正的硬链接,它也会报告2的硬链接计数。即使.并且..未出现在清单中,也可以打开目录,并stat可以使用名称.或调用目录..。在Linux上,链接数是0,但...同样仍然工作。

Mac OS X还报告目录中所有文件的数量作为链接计数,而不只是子目录的数量。但是即使...消失也为2 。


*这包括正常的打开描述符,内存映射的部分(包括执行二进制文件和共享库)以及处理当前目录。


2
strcpy到setuid可执行文件中的固定大小数组上……这是美好的时光!
Andrea Corbellini 2015年

@AndreaCorbellini实际上有一个已发布的利用程序,其mkdir基于事实是它必须做相反的事情。
Random832


问一下rmdir,是否会通过removein ..删除父目录?
爱德华·托瓦尔兹

@edwardtorvalds不,我是指删除“ ..”链接本身,而不是指向它的父目录。
Random832 '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.