什么叫软链接?
在Linux操作系统中,文件系统的核心概念之一是链接,包括软链接(符号链接)和硬链接。这些链接提供了访问文件系统中文件的灵活方式。软链接,被称为符号链接。类似于windows下的一个快捷方式。其本身也是一个文件,有着自己独立的inode。该文件的内容是链接对象文件的路径。这也是我们为什么可以通过快捷方式打开目标文件。
随便观察一个软连接:
结合对前面对文件系统的理解,inode其实是一个指向文件数据的一个指针。创建软链接,其实就是创建了另一个指针,指向的是原始文件的路径。
值得注意的是,rm
指令删除文件时并不会考虑该文件是否是一个软链接,也就不会影响到原来的文件。其余大部分操作都会通过软链接影响到原文件,比如chmod
修改权限。
用ln -s指令创建软链接
格式:
ln -s 目标文件 软链接名
现给出一个文件test.txt,并为其创建一个软链接:
用ll -i
观察软链接的inode和目标文件的inode:
得出结论:软链接是一个独立的文件,有着自己独立的inode。
尝试在其它文件目录下创建一个test.txt的软链接,并访问:
这里可以得出结论:通过软链接可以访问原来的文件(跨目录访问)。
软链接的特点
- 软链接包含的是另一个文件的路径,而不是直接指向文件数据的inode。
- 如果原始文件被移动或删除,软链接就会失效,因为它的路径不再有效,这种情况下软链接被称为悬空链接。
- 软链接可以跨文件系统,因为它仅仅保存了另一个文件的路径。
为什么说软链接可以更灵活的访问文件呢?
因为很多时候我们有的文件会在非常深的路径下面,通过路径去找到这个文件往往会比较麻烦。例如给出一个文件test,其路径结构为:
现实的文件系统中的文件可能比这还要复杂许多。当我们想要在其他目录下直接访问这个test,可以考虑建立一个软链接:
这样一来就可以通过这个软链接直接访问其它目录的文件了。
软链接的工作原理
- 软链接是文件系统中的一个特殊文件类型,存储的是目标文件的路径信息。操作系统访问到软链接的时候会重定向到路径指向的目录或者路径。
- 操作系统是怎么识别一个文件是否是软链接的呢?软链接的文件类型标识符会被标记为
l
:
这样操作系统就能在马上知道一个文件是否是软链接了。
- 软连接的权限和被指向的目标文件无关。即使软链接指向一个不可读的文件,软链接本身的权限也是可读的。这也是为什么我们创建出来的软链接的权限掩码是777.有趣的是,我们并不能对一个软链接本身修改其权限,当我们尝试用chmod指令修改一个软链接的权限时,操作系统会直接跳过软链接而去修改它所指向的文件。从设计角度上来说,软链接只是一个“表象”,控制软链接的权限也没有太多意义。所以,对于操作系统来说,软链接只需要提供两点信息就可以了:一是告诉操作系统自己是一个软链接文件,二是目标文件的路径信息。
- 当用户通过软链接访问文件时,操作系统内核首先检查链接指向的路径。如果路径有效,操作系统就转向该路径并完成相应的文件操作。如果目标文件被移动或删除,软链接就会失效,称为悬挂链接(dangling link),因为它指向了一个不存在的路径。
什么叫硬链接
硬链接是指向文件系统中某个文件的实际数据的直接指针。在技术上讲,硬链接是文件实际数据的另一个名字(或指针)。创建出来的硬链接会复用原来文件的inode,也就意味着硬链接并不是一个独立的文件。
用ln指令创建硬链接
格式:ln 目标文件 链接名
观察创建硬链接的结果:
果然,创建的硬链接inode与原文件的inode是一样的。
硬链接的原理
- 创建硬链接实际上是在文件系统中创建一个额外的目录条目,指向同一个inode。因此,原始文件和硬链接共享同一个inode和文件数据。
- 对硬链接的任何修改都会反映在原始文件上
- 每个inode有一个引用计数,表示有多少文件名(目录条目)指向这个inode。当创建硬链接时,相关inode的引用计数会增加。当删除文件名时,引用计数减少。只有当引用计数达到零时,文件的数据和inode才会被系统回收。在文件属性中可以看到一个文件的硬链接数量:
这个硬链接数量其实是值指有多少个inode指向该文件的内容。
硬链接的特点
- 节省空间:硬链接只是增加了一个新的目录条目,即indoe映射。并没有开额外的空间来存储文件数据。
- 备份和共享方便:通过硬链接,我们可以在不同的路径下创建指向相同文件内容的路口,有助于数据的共享和备份,尤其对于大文件来说。
- 即时更新:由于同一文件的所有的硬链接都是指向同一inode,对原始文件或任何硬链接的修改会即时反映在所有链接上,因为它们共享相同的数据。
- 不能链接目录:硬链接不能链接目录,防止循环引用,这可能导致目录遍历算法陷入无限递归。
- 硬链接 不能跨文件系统,因为不同的文件系统的indoe表不同。
- 删除复杂:多个硬链接指向同一个文件时,删除操作需要谨慎处理。每次删除一个硬链接文件,其实是使该inode引用数-1,直到为0才是真正的删除。
其实硬链接可以链接目录,只不过这是由操作系统自己去做的。比如我们创建一个目录后,.
和..
其实就是一个硬链接:
我们进入A目录后观察.
的inode,发现和A目录的inode是一样的!这也能解释为什们我们的.
表示的就是当前目录
同理..
其实就是上一级目录的硬链接。
之所以不给用户创建目录的硬链接,是因为出于安全考虑。
进一步理解为什么硬链接不能链接目录
假设这样一个场景:
我们有一个目录结构,包括目录A和目录B。如果系统允许硬链接目录,我们可能会执行以下操作:
- 创建目录A和B
- 在A目录下创建B的硬链接
- 在B目录下创建A的硬链接
导致产生以下目录结构:
A -> B -> A -> B -> ... • 1
假设我们试图遍历目录A的内容时,会找到B,进入B之后又回到了A,此后这个过程便无限循环下去了。
那问题来了,为什么.
和..
不会引发循环遍历呢?
虽然看起来确实会引发无限循环,但是设计者在设计之前就考虑到了这一点,采取了以下措施来防止.和..造成死循环:
1.在尝试进入.时,系统知道这个目录就是当前目录,所以就不会进去。
2.根目录的..指向自己,使得回到上级目录的次数是有限的。
3.遍历目录的时候,遍历算法会智能地忽略或适当处理对.和…的访问,从而防止无限循环。
总的来说,这是操作系统操心的事,我们无需心其细节。
问题又来了,为什么用户可以软链接目录呢?
软链接避免死循环的关键在于软链接本身并不修改文件系统的实际物理结构。它们只是提供了到另一个位置的引用,而文件系统的遍历工具通常可以识别出软链接并决定如何处理它们(通常是不展开或者只展开一层)。即使逻辑上看起来有循环引用的风险,物理层面上的目录结构并未形成真正的闭环,因此遍历操作不会陷入无限循环。
得了,又是系统自己的事情。