软/硬链接
目录
一、概述
二、软/硬链接的创建与删除
三、理解软/硬链接
1. 理解硬链接
2. 理解软链接
四、软/硬链接的应用
1. 软链接的应用
2. 硬链接的应用
2.1 为什么普通用户不能给目录创建硬链接
五、Access、Modify、Change
一、概述
软链接:
- 软链接是一个特殊的文件,其内容是另一个文件或目录的路径名。当访问软链接时,系统会通过该路径名找到并访问目标文件或目录。
- 软链接类似于Windows系统中的快捷方式,它存储的是目标文件的路径,而不是文件本身的数据。
硬链接:
- 硬链接是另一个文件的名称,与原始文件共享相同的inode(索引节点)信息。
- 在Linux系统中,每个文件都有一个唯一的 inode 号,硬链接通过指向同一个 inode 号来实现对文件的访问。
二、软/硬链接的创建与删除
- 创建一个软链接文件。
命令:ln -s [目标文件或目录] [链接名]
其中,ln 表示 link,s 表示 soft 。
我们会发现:
- 新创建的软链接文件的类型为 “l”,“l” 指的就是链接文件。
- 软链接文件有自己的 inode。【既然它有独立的 inode,说明它就是一个独立的文件。】
- 链接数为 1。
- 创建一个硬链接。
命令:ln [目标文件] [链接名]
我们会发现:
- 用硬链接的方式创建的文件和目标文件的类型是一样的。
- 用硬链接的方式创建的文件没有自己的 inode。
- 链接数变为了 2。
因此,我们就得到了:
软链接和硬链接的最大区别为:是否具有独立的 inode。
- 删除一个软 / 硬链接:
命令:unlink 链接名
三、理解软/硬链接
1. 理解硬链接
建立一个硬链接到底做了什么呢?
通过上图会发现:这个硬链接除了名字和原来的文件不一样,其它属性都是一样的。
同时,我们会发现:当 myfile.txt 大小发生变化时,硬链接的大小也跟着变化了。软链接的大小没有变。
并且,当我们使用 cat 命令查看文件内容时,会发现:硬链接显示的内容和原文件的内容是一样的。
所以,建立硬链接,根本就没有创建新文件。因为没有给硬链接分配独立的 inode。 既然没有创建新文件,那么,硬链接就一定没有自己的属性集合和内容集合。它用的一定是别人的 inode 和内容。
所以,我们可以得到这样一张图:
通过上图我们可以得到:建立一个硬链接,就是在指定的路径下,新增文件名和 inode 编号的映射关系。
其实,在每个 inode 里面都有一个引用计数,表示指向该 inode 的硬链接(目录项)数量。每当创建一个新的硬链接时,引用计数会增加;删除一个硬链接时,引用计数会减少。
所以,当我们没创建硬链接的时候,myfile.txt 的硬链接数为 1 ;当我们创建硬链接之后, myfile.txt 的硬链接数就变为为 2 了。
如果我们把 myfile.txt 给删除掉会怎样呢?
我们会发现:软链接的指向已经发生问题了,因为它所指向的文件被删了。我们这里先不管。
但是,我们也会发现:我们的硬链接所指向的文件还在,并且引用计数变为1了。这就说明:我们已经去掉了一组映射关系。
所以,什么时候一个文件才算真正被删除呢?
当一个文件的硬链接数变为 0 的时候,这个文件才算是真正的被删除了。
2. 理解软链接
通过上图,我们会发现:当我们将软链接曾经所指向的文件名给删除后,它就会疯狂闪烁。
并且,它还会告诉我们,这个文件不存在。
可是,事实上,这个文件(1323250)其实还存在。
如果我们再创建一个 myfile.txt。
我们会发现:这个软链接又有用了。虽然它已不再是曾经的它了。
所以,我们可以得到:软链接在标定一个文件的时候,它不是用目标文件的 inode 标定的,而是用目标文件的文件名标定的。
我们知道:软链接是一个独立文件,它有自己的 inode,也有自己的数据块。
inode 是用来存属性的。那么,它的数据块里面存什么呢?
其实,它的数据块里面保存的就是所指向的目标文件的路径。所以,当我们将目标文件名给删除了,在软链接看来,这个文件就被删除了,这个软链接也就失效了。
那么,软 / 硬链接有哪些应用场景呢?
四、软/硬链接的应用
1. 软链接的应用
我们上面说过,其实软链接就对应于Windows上的快捷方式。既然是快捷方式,那么它就一定能够帮我们快速的定位一个文件。
假设在 myfile/Test 里面有一个可执行文件 test ,如果我们没有用软链接,我们要执行它可能就会带一长串路径。
如果我们创建一个软链接:
会发现:我们照样可以用软链接的方式运行这个程序。
所以,软链接的应用就在于这里。
2. 硬链接的应用
当我们创建一个普通文件和空目录:
我们会发现:普通文件默认的引用计数为 1,空目录默认的引用计数为 2。
那么,为什么一个普通文件默认的引用计数为 1 呢?
因为一个普通文件本身就有一个文件名、一个自己的 inode 以及对应的一个映射关系。 所以,引用计数为 1。
那么,为什么一个空目录默认的引用计数为 2 呢?
当我们查看这个空目录的属性时,会发现:
它的 inode 为 1323251。
当我们进入空目录,并且查看被隐藏的目录时:
我们知道:‘.’ 指的就是当前目录,这就意味着:‘.’ 就是 empty 。因为 ‘.’ 和 empty 的 inode 都是1323251。这也就意味着:‘.’ 是 empty 的硬链接。所以,空目录默认的引用计数为 2 。
如果我们在 empty 目录下再创建一个空目录 mydir :
我们会发现:mydir 的 默认引用计数也为 2,这没什么问题。
但是,当我们退出来后:
我们会发现:empty 这个目录的引用计数变为 3 了。
原因就在于:当我们在一个目录下面再创建一个目录时,里面的那一个目录(mydir)里面会有一个 “..” ,它表示上级目录,它其实也是 empty 的硬链接。所以,引用计数就变为 3 了。
2.1 为什么普通用户不能给目录创建硬链接
当我们给目录创建硬链接的时候:
我们会发现:Linux不允许普通用户给目录建立硬链接。
当我们给目录创建软链接的时候:
我们会发现:我们可以给目录创建软链接。
为什么会出现这样的现象呢?
原因就在于:
- 1. 保障文件系统的完整性
硬链接使多个文件路径指向同一文件系统对象。如果允许对目录建立硬链接,可能导致循环引用(例如,一个目录成为自己的父目录),从而破坏文件系统的层次结构。
目录结构是树状的,硬链接可能打破这种树状结构,导致文件系统操作(如遍历、备份等)变得复杂甚至失败。
- 2. 避免无限递归
如果目录之间通过硬链接形成循环,文件系统的遍历操作(如 ls、find)可能陷入无限递归,导致系统性能下降甚至崩溃。
- 3. 权限与安全问题
目录硬链接可能被恶意利用来绕过权限检查。例如,用户可以通过硬链接创建某种路径,访问原本无权访问的目录。
- 4. 文件系统设计
Linux和大多数类Unix系统中,目录硬链接仅允许由内核在特定情况下创建(例如,父目录对子目录的引用是硬链接)。
常规用户无法通过API直接操作创建目录硬链接。ln 命令也明确限制了这项功能。
- 5. 软链接的存在
符号链接(软链接)可以实现大部分普通用户对目录链接的需求,而不会破坏文件系统的树形结构。软链接是一种更灵活、安全的解决方案。
- 例外情况
尽管普通用户不能对目录创建硬链接,超级用户(root) 在某些文件系统中可能通过低级命令或特殊工具(如 debugfs)强制创建。但这通常不推荐,因为可能导致系统不稳定或难以维护。
- 总结
限制普通用户对目录创建硬链接是为了保障文件系统的完整性、安全性以及操作的可预测性。如果需要链接目录,可以使用符号链接(ln -s),这是一种更安全的替代方案。
最后,我们再来讲一下Access、Modify、Change三个时间。
五、Access、Modify、Change
- 对于Change:它指的是文件属性最近被修改的时间。由于文件=属性+内容。自然我们可以只修改文件的属性。
修改文件的权限:
会发现:Change时间发生了变化,其它时间没有变。
- 对于Modify:它指的是文件内容最近被修改的时间。由于我们将文件内容给修改了,那么,这个文件的属性大概率也会被改变(比如:文件大小发生变化)。所以,当Modify时间发生改变,Change时间也会跟着改变。
在文件里面添加内容:
会发现:Modify时间和Change时间都发生了变化。
- 对于Access:它指的是文件被访问的时间。但是,Access是要访问达到一定次数后才会更改。原因是:一般访问文件的次数是很多的,所以Access就会被频繁更改。由于我们的文件是存放在磁盘的,所以操作系统就会频繁的访问磁盘。这会对系统带来负担。同时,其实我们也不会去关注一个人在什么时候访问了文件。既然都把权限放开了,还在乎他什么时候访问了文件吗?不想让人访问文件,改文件权限就可以了。所以,Access是要访问达到一定次数后才会更改。
访问文件:
会发现:Access时间在我们多次访问文件后并没有发生改变。