这只是一个坏主意,因为无法分辨硬链接和原始名称之间的区别。
允许对目录的硬链接将破坏文件系统的有向无环图结构,可能会创建目录循环并悬挂目录子树,这将使fsck
文件树和其他文件树更容易出错。
首先,要了解这一点,让我们讨论一下索引节点。文件系统中的数据保存在磁盘上的块中,这些块由一个索引节点收集在一起。您可以将inode视为THE文件。索引节点缺少文件名。那就是链接进入的地方。
链接只是指向索引节点的指针。目录是保存链接的索引节点。目录中的每个文件名都只是指向索引节点的链接。在Unix中打开文件也会创建一个链接,但这是另一种类型的链接(不是命名链接)。
硬链接只是指向该索引节点的额外目录条目。当您使用时ls -l
,权限后的数字就是命名的链接数。大多数常规文件将具有一个链接。创建指向文件的新硬链接将使两个文件名都指向同一inode。注意:
% ls -l test
ls: test: No such file or directory
% touch test
% ls -l test
-rw-r--r-- 1 danny staff 0 Oct 13 17:58 test
% ln test test2
% ls -l test*
-rw-r--r-- 2 danny staff 0 Oct 13 17:58 test
-rw-r--r-- 2 danny staff 0 Oct 13 17:58 test2
% touch test3
% ls -l test*
-rw-r--r-- 2 danny staff 0 Oct 13 17:58 test
-rw-r--r-- 2 danny staff 0 Oct 13 17:58 test2
-rw-r--r-- 1 danny staff 0 Oct 13 17:59 test3
^
^ this is the link count
现在,您可以清楚地看到没有硬链接之类的东西。硬链接与常规名称相同。在上面的示例test
或中test2
,哪个是原始文件,哪个是硬链接?最后,您无法真正分辨(即使按时间戳记),因为两个名称都指向相同的内容,相同的索引节点:
% ls -li test*
14445750 -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test
14445750 -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test2
14445892 -rw-r--r-- 1 danny staff 0 Oct 13 17:59 test3
该-i
标志ls
在行首显示您的inode编号。请注意,如何test
和test2
具有相同的inode编号,但test3
具有不同的inode编号。
现在,如果允许您对目录执行此操作,则文件系统中不同点的两个不同目录可能指向同一对象。实际上,子目录可以指向其祖父母,从而创建一个循环。
为什么要关注此循环?因为在遍历时,无法检测到是否在循环(遍历时不跟踪inode编号)。假设您正在编写该du
命令,该命令需要通过子目录递归以了解磁盘使用情况。怎么du
知道它何时陷入循环?du
仅仅是为了完成这个简单的任务,就容易出错并且需要做很多记账工作。
符号链接是完全不同的野兽,因为它们是一种特殊的“文件”类型,许多文件文件系统API往往会自动遵循它们。注意,符号链接可以指向不存在的目的地,因为它们是按名称指向的,而不是直接指向inode的。该概念对于硬链接没有意义,因为仅存在“硬链接”就意味着文件存在。
那么,为什么可以du
轻松地处理符号链接而不是硬链接呢?上面我们可以看到,硬链接与普通目录条目没有区别。但是,符号链接是特殊的,可检测的和可跳过的!
du
注意符号链接是符号链接,并完全跳过了它!
% ls -l
total 4
drwxr-xr-x 3 danny staff 102 Oct 13 18:14 test1/
lrwxr-xr-x 1 danny staff 5 Oct 13 18:13 test2@ -> test1
% du -ah
242M ./test1/bigfile
242M ./test1
4.0K ./test2
242M .
..
指向哪里?尤其是在删除指向该目录的硬链接之后,在..
?指向的目录中。它需要指向某个地方。