硬链接与软链接(符号链接)

97 篇文章 7 订阅

硬链接与软链接(符号链接)

软链接即符号链接。

在Unix以及类Unix系统中常可以见到这两个概念:软链接、硬链接。

那么什么是软链接,什么是硬链接呢?

首先说下什么是文件。

所谓文件,我个人认为其实就是i节点加上实际存储数据的数据块。
i节点保存关于文件的大部分相关信息,类似文件长度啦,文件的访问权限位啦,指向数据块的指针啦等等,与此文件有关联的目录项的个数(硬链接),也是被包含在i节点中(详见下文)。

额,忘记说了,那啥是i节点呀?

我们需要先有一个概念:

一个磁盘可以有好几个分区,而每个分区,其实都可以有一个自己的文件系统。

i节点是一个对象(或者可以说一个结构),这个i节点存储在一个文件系统中,每个i节点有一个i节点编号,此编号在一个文件系统中是唯一的。

啊,总结起来就是说,在一个FileSystem中有一个数组,数组下标就是i节点编号,数组的每个元素就是一个一个的i节点啦。

那一个FileSystem中除了这个i节点组成的数组,还有别的东西没?

有,当然有,要不你以为真正的数据存在哪里呀?

一个文件系统除了包含i节点数组以外,还包括数据块,文件内容就保存在数据块中。

啊,那再总结下,就是一个FS中包含i节点数组以及很多数据块。

现在来看什么是文件?文件是一个i节点以及很多存储文件实际内容的数据块构成的。

小伙伴们有没有感觉上面的逻辑像是一个递归,哈哈。
上述递归到此结束~

简单来说,建立一个软链接,实际是新建立一个文件,将会为其分配i节点以及数据块。而建立一个硬链接,这是新建立一个目录项(详见下文),这个目录项指向已存在的一个i节点,也就是把这个目录项与i节点关联起来,并无i节点分配以及数据块的分配。

什么是目录项。

我们知道,在Linux/Unix中所有的都是文件,目录也是一种文件,只是这种文件比较特别罢了,能对其进行cd等等。但是其既然是个文件,那么一个目录也是有其对应的i节点以及数据块。

目录的数据块记录什么信息呢?

答案是目录项。

所谓目录项,可以简单认为是由一个文件名字加上一个i节点编号组成的。

这里写图片描述

一个目录的实际数据块存储的逻辑内容应该是上图那样子滴。

我们平时ls看到的其实都是目录项的名字。

当建立一个硬链接的时候,其代表的含义是建立一个目录项,这个新建立的目录项的i节点编号与某个已存在的文件中的i节点编号相同。

BTW:

[root@localhost mylink]# ll
total 0
[root@localhost mylink]# echo "this is file-a" >> a
[root@localhost mylink]# ll
total 8
-rw-r--r-- 1 root root 15 Mar 19 09:49 a

有没有注意过访问权限位后面那个1是干什么的?

那个就是上文所说的与这个文件有关的目录项的个数(这里的目录项指的是硬链接,不是软链接,所以这个1代表的是这个文件在当前文件系统中有几个硬链接指向它)。

[root@localhost mylink]# ls -i
1015885 a

第一列的值就是i节点在本文件系统中的唯一编号。

我建立一个新的硬链接:

[root@localhost mylink]# ln a b
[root@localhost mylink]# ll -i
total 16
1015885 -rw-r--r-- 2 root root 15 Mar 19 09:49 a
1015885 -rw-r--r-- 2 root root 15 Mar 19 09:49 b

发现他们的i节点编号相同,代表着什么?代表着这两个目录项背后实际是同一个文件(两个目录项指向同一个i节点)。

我再建立一个软链接:

[root@localhost mylink]# ln -s a c
[root@localhost mylink]# ll -ai
total 36
1015819 drwxr-xr-x  2 root root 4096 Mar 19 09:56 .
1015809 drwxr-x--- 15 root root 4096 Mar 19 09:49 ..
1015885 -rw-r--r--  2 root root   15 Mar 19 09:49 a
1015885 -rw-r--r--  2 root root   15 Mar 19 09:49 b
1015886 lrwxrwxrwx  1 root root    1 Mar 19 09:56 c -> a

发现这个新建的目录项(文件名字是c)的i节点编号和上面的不一样呀。

还记得我在一开始说的吗?

建立软链接,等价于建立一个新的文件(不是如同硬链接那样建立一个新的目录项),在建立新的文件过程中,会分配数据块以及i节点。

建立软链接后产生的这个文件,它的数据块存储了什么呢?

[root@localhost mylink]# ln -s /usr/lib mylib
[root@localhost mylink]# ll -ai
total 40
1015819 drwxr-xr-x  2 root root 4096 Mar 19 10:01 .
1015809 drwxr-x--- 15 root root 4096 Mar 19 09:49 ..
1015885 -rw-r--r--  2 root root   15 Mar 19 09:49 a
1015885 -rw-r--r--  2 root root   15 Mar 19 09:49 b
1015886 lrwxrwxrwx  1 root root    1 Mar 19 09:56 c -> a
1015887 lrwxrwxrwx  1 root root    8 Mar 19 10:01 mylib -> /usr/lib

第一列是目录项中的i节点编号;
第三列是当前有多少个目录项(硬链接)指向这个文件;
第六列是当前这个目录项指向的文件的大小,单位字节。

可以看到最后一个,mylib这个软链接文件,它的大小是8B,看看它指向的文件的路径?“/usr/lib”,恰好8个字节长度。

也就是说,软链接所创建的文件的内容实际是目标文件的路径(字符串)。

另外再提一些:

1.
软链接可以随意建立(可以对目录或者普通文件建立软链接),即使是指向的文件并不存在,因为在建立软链接过程中创建的那个文件的内容实际是一个路径,至于路径指向的文件是否存在,那无所谓了。

2.
硬链接不能随意建立。很多系统中都不能对目录建立硬链接,这是出现软链接的一个重要因素。因为可能循环,导致很多工具不能正常使用,所以禁止对目录建立硬链接。

3.
硬链接不能跨越文件系统。原因在你看明白上述的解释很清晰,是因为硬链接实际是一个目录项,这个目录项包含文件名字和i节点编号,这个i节点编号只在当前文件系统中有效,至于到了别的文件系统。。那直接就是一个污数据了。。。完全没意义了呀。符号链接可以跨越文件系统(磁盘分区)。

如果你还没明白,你可以看下下面的例子:

【1】

[root@localhost mylink]# ll
total 0

【2】

[root@localhost mylink]# echo "this is file-a" >> a
[root@localhost mylink]# ll -ai
total 24
1015819 drwxr-xr-x  2 root root 4096 Mar 19 10:22 .
1015809 drwxr-x--- 15 root root 4096 Mar 19 09:49 ..
1015885 -rw-r--r--  1 root root   15 Mar 19 10:22 a

在上述过程中,创建了一个文件,给其内容赋值(”this is file-a”),并在当前目录建立了一个新的硬链接,指向这个文件。

ps:
这个文件的i节点编号是1015885。
注:可以看出,判断两个目录项指向的文件是不是同一个,可以通过看他们的i节点编号是否相同来进行。

【3】

[root@localhost mylink]# ln a b
[root@localhost mylink]# ll -ai
total 32
1015819 drwxr-xr-x  2 root root 4096 Mar 19 10:24 .
1015809 drwxr-x--- 15 root root 4096 Mar 19 09:49 ..
1015885 -rw-r--r--  2 root root   15 Mar 19 10:22 a
1015885 -rw-r--r--  2 root root   15 Mar 19 10:22 b

上述创建了一个新的硬链接(目录项),指向之前创建的那个文件。

【4】

[root@localhost mylink]# ln -s a c
[root@localhost mylink]# ll -ai
total 36
1015819 drwxr-xr-x  2 root root 4096 Mar 19 10:26 .
1015809 drwxr-x--- 15 root root 4096 Mar 19 09:49 ..
1015885 -rw-r--r--  2 root root   15 Mar 19 10:22 a
1015885 -rw-r--r--  2 root root   15 Mar 19 10:22 b
1015886 lrwxrwxrwx  1 root root    1 Mar 19 10:26 c -> a

创建了一个新的文件,其对应的i节点编号是1015886,其内容为字符串”a”(路径),文件大小是1B,并在当前目录创建了一个硬链接(或者说目录项),指向那个新文件。

由此看来,第一次创建的新文件对应的i节点值是1015885,第二次创建的新文件对应的节点值是1015886,是两个完全不一样的文件。

额,到现在应该明白了吧?

最后再啰嗦一句,当一个i节点的依赖项数(指向该i节点的目录项)值为0时,才会回收此i节点以及对应的数据块,只要依赖项数大于0,那么就不会回收。

所以,你对一个文件rm一下,只是删除这个文件在当前目录中的一个分身(目录项),至于到底删没删。。那你应该看还有没有别的硬链接指向它,请看下面的例子:

[root@localhost mylink]# ll -ai
total 36
1015819 drwxr-xr-x  2 root root 4096 Mar 19 10:26 .
1015809 drwxr-x--- 15 root root 4096 Mar 19 09:49 ..
1015885 -rw-r--r--  2 root root   15 Mar 19 10:22 a
1015885 -rw-r--r--  2 root root   15 Mar 19 10:22 b
1015886 lrwxrwxrwx  1 root root    1 Mar 19 10:26 c -> a
[root@localhost mylink]# rm a
rm: remove regular file `a'? y
[root@localhost mylink]# cat b
this is file-a
[root@localhost mylink]# 

本文我没用那些文绉绉的词汇,如果你指针学的不错的话,理解起来应该很容易~

如果我有技术错误,还请大家指出~谢谢喽!

额,写这么多技术外链不知道会不会被封号,哈~

参考资料:
http://www.ibm.com/developerworks/cn/linux/l-cn-hardandsymb-links/
http://blog.csdn.net/diana_cherry/article/details/7230798
http://www.jianshu.com/p/dde6a01c4094
https://zhidao.baidu.com/question/1797277860057284227.html
http://www.2cto.com/os/201312/266882.html
http://blog.sina.com.cn/s/blog_5ac88b350100auh9.html
http://www.cnblogs.com/itech/archive/2009/04/10/1433052.html
http://blog.csdn.net/mahao1107/article/details/46851969
http://blog.chinaunix.net/uid-23208702-id-75180.html

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值