(Linux 文件系统)一张图解释什么是硬链接什么是软链接
[ ]The content is recoverd from Wordpress Blog, for more details please check HERE
August 13, 2016
= = 不知道我有多久没更新博客了(观众: 这种好吃懒做不上进的博主赶紧打包卖到幻想乡被妖怪吃了吧) 我: 诶, 真不错诶! 快把我打包去幻想乡窝要见灵梦还有紫妈! &^X^(**啊窝错了&^#^@#@(不要这么对我Y)IH [博主被打包中… 请稍后] 这么久没更新博客真的是很抱歉 各种事情加上自己最近也没有继续研究太多底层相关的东西, 公司的项目的体量有点大导致窝晚上回来没有好好码字学东西qwq, 好了闲话就说到这里, 下面是正文
Linux 文件系统里的硬链接(hard link) 和软(符号)链接 (softlink)
很多刚刚接触Linux文件系统的同学包括有些接触了文件系统一阵子的同学还是会对软链接和硬链接有疑问, (比如我, 划掉)那么下面我们就借助一个简单的例子来了解一下什么是软链接什么是硬链接, 概念我就不说了, 想要看这个文章,首先要懂得什么是inode, datablock, 下面我们在tmp文件夹下做一个小实验
mkdir havefun
cd havefun
echo "Hello hard&soft link" >> void001
ln void001 void001.hard
ln -s void001 void001.soft
好辣, 我们现在就已经创建了一个叫做void001的文件,以及她的软和硬两个链接, 窝们如何区分软硬链接呢? 首先, 软链接在ls的时候(–color=auto/always)会用特殊的颜色标明出来, 不过这不是本质区别啦= =, 本质的区别在于, 软链接会占用一个新的inode, 而硬链接, 不会占用新的inode, 只是在目录block中增添了一条目录项记录, 并且指向了void001对应的那个inode.
为了证明我们上述说的,我们用ls -ali
来看一下(画外音: -ali 才不是阿里呢, 只不过凑巧被窝排成了这个顺序而已), 下面的输出结果为了与图片的信息完全匹配, inode index被窝处理过了, 只是把数字进行了一个替换而已, 不影响解释原理, 原本的数字用括号注明了
[[email protected]](/web/20210418233342/https://void-shana.moe/cdn-cgi/l/email-protection):/tmp/havefun# ls -ali
total 8
4723004 drwxr-xr-x 2 root root 4096 Aug 13 08:58 .
4719827 drwxrwxrwt 3 root root 4096 Aug 13 08:53 ..
# Below can be omitted
2033(4723005) -rw-r--r-- 2 root root 0 Aug 13 08:58 void001
2033(4723005) -rw-r--r-- 2 root root 0 Aug 13 08:58 void001.hard
2029(4723006) lrwxrwxrwx 1 root root 7 Aug 13 08:58 void001.soft -> void001
这里,我们可以看出, void001, 和其创建的hard link的inode index是一样的, 而void001.soft却是不同的,这正是软链接和硬链接的区别, 再看旁边的数字, 从void001 开始 从上到下 为 2 2 1, 这个叫引用计数,指有多少个目录项指向了当前的inode, 我们通过这个也可以看出来, 2033 这个inode被引用(指向)了两次, 而 2029 只有一次, 这也说明了void001.hard指向了2033这个inode, void001.soft没有指向它,因为如果void001.soft也指向了2033这个inode的话, 那么2033的引用计数就应该为3而不是2了, 那么 void001.soft 通过什么方式指向某一个文件呢, 它通过的方式就是保存文件名, 我们可以看到, void001.soft指向了一个新的inode, 这个inode又会指向一个新的数据块, 这个数据块内存储了, void001.soft指向的文件的路径名(绝对路径), 并且这个inode(2029)的属性为 soft link, 因而我们的文件系统以及相应程序,就可以通过这个路径名,再次找到那个文件的inode并且读取它
说了这么多, 还不如一张图来的直观, 我们来看一下这张图, 结合上述描述,在对照这个图片来看, 相信你就对硬链接和软链接有一个很好的了解了
图中紫色部分为inode数组, 绿色部分为数据块, 我们可以清晰地看出来, 2033的被指向了两次, 因而他的引用计数为2, 2029只被指向一次, 而且它还指向一个数据块,这个数据块内存着void001这个文件的绝对路径名
指向它所在文件夹的hardlink
那么, 我们还会发现一个神奇的事情, 当我们想要给一个文件夹创建一个hard link的时候, 系统会提示 hard link not allowed for directory 这是为什么呢? 这也是有原因的, 我们看一下下图
我们可以看出来, 这个图中, 我建立了一个hardlink指向这个文件夹本身, 那么这个会有什么后果呢?
首先我们要知道的是, hardlink和普通文件一样, 不同于soft link没有一个类型标识他为hard link, 所以系统会把这个hard link当做一个普通文件, 去访问它的inode
那么当我们要遍历目录查询文件(用find/grep之类的指令)或者是某些程序需要遍历目录的时候, 那么就会发生难以想象的灾难:
首先访问到/tmp/havefun这个文件夹, 然后 找到了 void001(硬链接的名字), 然后找到了对应的 2033 inode,发现是一个文件夹, 然后继续访问这个文件夹, 然后再次找到void001…
形成了死循环
这种环还会引起很多问题, 感兴趣的可以深入了解一下
因而, 在现在的系统中, 是不允许用户创建指向文件夹的硬链接的
这里以一个关于古时硬链接文件夹引起的悲剧小故事结束本文
当 Rich Stevens (APUE的作者) 在写硬链接的相应介绍时, 为了研究链接向自己的硬链接, 亲自在自己的系统上做了一个实验, 结果导致他的文件系统错误百出, 正常的fsck都不能修复问题, 为了修复文件系统,他不得不用了不推荐使用的工具clri和dcheck — 摘自APUE
Linux, 计算机系统原理 C. Linux, kernel, Laravel, PHP, Python, Shell, Web, wine
Historical Comments
VOID001 says: August 13, 2016 at 5:39 pm 哦对了我发现hard link在图片上的位置有问题, 不过没事, 忽略掉就可以啦w, 因为图片底稿已经修改了再改回去比较麻烦所以就不改惹, 文章已经说的很清楚了哪个是hardlink哪个是softlink
VOID001 says: August 13, 2016 at 5:39 pm 哦对了我发现hard link在图片上的位置有问题, 不过没事, 忽略掉就可以啦w, 因为图片底稿已经修改了再改回去比较麻烦所以就不改惹, 文章已经说的很清楚了哪个是hardlink哪个是softlink