深入理解unix中的普通链接与符号链接
概述
在 unix/linux
的使用过程中不可避免的要使用 ln
命令,可以说文件链接是 unix
的一大特色。但是要说清楚 ln
命令具体是怎么回事,我们避免要结合 unix
的文件系统的来加以说明。好,闲话稍许,我们下边开始。
unix 中的文件系统
unix
支持的文件系统有多种,为了便于说明我们针对其主流的文件系统 ext4
来加以说明,首先 ext4
是是 linux
中第四代日志文件系统,其结构示意图如下图所示:
ext4
文件系统会把分区主要分为两大部分(暂时不提超级块):小部分用于保存文件的 inode
信息;剩余的大部分用于保存 block 信息。
inode
的默认大小为 128 Byte,用来记录文件的权限(r、w、x)、文件的所有者和属组、文件的大小、文件的状态改变时间(ctime)、文件的最近一次读取时间(atime)、文件的最近一次修改时间(mtime)、文件的数据真正保存的 block 编号等静态参数。每个文件需要占用一个 inode
。大家如果仔细查看,就会发现 inode
中是不记录文件名的,那是因为文件名记录在文件所在目录的 block 中。
block
的大小可以是 1KB、2KB、4KB,默认为 4KB。block
用于实际的数据存储,如果一个 block
放不下数据,则可以占用多个 block
。例如,有一个 10KB 的文件需要存储,则会占用 3 个 block
,虽然最后一个 block
不能占满,但也不能再放入其他文件的数据。这 3 个 block
有可能是连续的,也有可能是分散的。
当然上边描述了一大段对我们来说我们可以提取到以下两个关键信息:
- 每个文件都独自占用一个
inode
,文件内容由inode
的记录来指向其对应的block块
; - 如果想要读取文件内容,就必须借助目录中记录的文件名找到该文件的
inode
,才能成功找到文件内容所在的block 块
;
文件链接的原理
了解到上边两个关键信息后,我们接下来便可以详细说说 ln
命令其具体的原理和作用。
首先 ln
命令是用于建立 文件链接
,根据建立链接的底层实现不同我们可以将链接分为两类:
- 普通链接:又叫做硬链接,链接是直接指向
inode节点
的; - 字符链接:又叫做软链接,链接指向的是一个描述文件的“符号”
普通链接
普通链接本质上,可以理解不同的文件名指向同样的 inode,文件事实上只有一份。其整个结构可以结合下边的图来进行理解。
- 一个文件可有多个名字,多个名字都对应同一个文件节点,每个名字就是该文件节点的一个链结;
- 一个普通文件的名字个数,就是该文件的链结数;每个链接名可以放在不同的目录下(同一个文件下)
- 系统删除一个链接名时,文件链接数减一。如链接数不为零,则文件(节点)仍然存在。
结合上边的特点,我们可以发现普通链接有如下好处:
- 方便用户的使用习惯,如“列目录”,可用 ls、dir、 list、lc 等;
- 误删文件时可补救,又不多占空间。abc 和 xyz 具有相同的 i 结点号;
- 减少移植应用程序时,因使用指定位置的文件,而拷贝该文件到指定位置去的麻烦。
创建一个普通链接我们可以使用如下命令
ln 源文件 目标文件
符号链接
符号链接
,我们又称之为 软链接
,其本质上它是目录里的一种特殊项目,用来告诉系统实际文件的位置。类似于 windows 操作系统上边的快捷方式。其结构我们可以结合下图来进行理解。
- 给文件的名字再取一个名字,而不是给文件节点再取个名字。
- 链接的是“符号”而不是文件,因此“符号”可以是不存在的文件,即无意义的字符串。
- abc 和 xyz 具有不同的 inode 号,xyz 的内容是它所指向的名字的字符串,大小是字符串长度为 3 字节
- “普通链结”中各名字必须在同一文件系统中,“符号链结”可在不同的文件系统中。
创建一个符号链接我们可以多加上一个 -s
参数,使用如下命令来进行创建
ln -s 源文件 目标文件
总结
最后,我们对 普通链接
和 符号链接
来做一个简单的总结:
普通链接是直接对 inode 节点进行链接,在使用链接文件时直接可以找到 inode 节点上,而符号链接则是将链接指向了一个指向 inode 节点的符号,使用时先要找到该符号文件,然后通过该文件进一步找到 inode 节点。(有点类似于间接寻址的感觉)