【Linux】软链接与硬链接

1. 前置知识

1.1 硬盘

1.1.1 扇区

        硬盘不是一大块完整的区域,而是由很多扇区组成,每个扇区的容量为 512 字节。

1.1.2 分区

        硬盘的第一个扇区最重要,其中保存着主引导记录和分区表信息。在第一个扇区中,主引导记录(MBR,Master Boot Record)需要占用 446 字节,分区表为 64 字节,结束符占用 2 字节。分区表中每记录一个分区信息,需要 16 字节。综上,第一个扇区的分区表中只能记录 4 个分区信息,我们称之为主分区

硬盘第一个扇区数据信息示意

        按上文所述,第一个扇区最多创建 4 个分区,可能不能满足实际使用的需求。我们可以从第一个扇区的分区表中拿出 16 个字节,用它指向另一个分区。由于这部分空间本应写入一个主分区信息,现在却像指针一样指向另一个分区,所以称之为扩展分区。这种做法是 3 个主分区加 1 个扩展分区,然后在扩展分区中创建数个逻辑分区,从而满足多分区的需求。

        严格来说,扩展分区并非实际意义上的分区,它是指向下一个分区的指针,这种指针结构将形成一个单向链表。

主分区、扩展分区、逻辑分区示意

1.2 super block

        Linux 系统中的 super block 记录着整个文件系统的信息,譬如文件系统格式、文件系统中的节点数目、剩余节点情况、文件系统的大小和状态等。简而言之,super block 就像“硬盘地图”。

1.3 inode

        Linux 把每个文件的权限与属性记录在 inode 中,而且每个文件占用一个独立的 inode 表格,该表格的大小默认为 128 字节,里面记录着如下信息:

    • 该文件的访问权限(read、 write、 execute);

    • 该文件的所有者与所属组(owner、 group);

    • 该文件的大小(size);

    • 该文件的创建或内容修改时间(ctime);

    • 该文件的最后一次访问时间(atime);

    • 该文件的修改时间(mtime);

    • 文件的特殊权限(SUID、 SGID、 SBIT);

    • 该文件的真实数据地址(point)。 

        在 Linux 系统中,inode 号才是文件的唯一标识,不能靠文件名来区分。这一点和 Windows 差异较大,且和后续的硬链接有关,一定要理解。我们可以使用 ls -li 命令来查看文件的 inode 号。

1 ls -li
2 total xx
3 533124 drwxr-xr-x 9 apple apple 4096 May  4 10:22 apache-tomcat-8.5.41
4 360908 -rw-rw-r-- 1 apple apple   18 Jun  1 23:50 helloWolrd
5 360974 drwxr-xr-x 4 apple apple 4096 Jun  3 10:15 hi-cat
6 393217 drwxrwxr-x 6 apple apple 4096 May 28 09:37 program
7 518079 drwxrwxr-x 3 apple apple 4096 Mar  4 11:31 project

1.4 block

        文件的实际内容保存在 block 块中,其大小可以是 1KB、2KB、4KB。上个小节提到,一个 inode 的默认大小是 128B,记录一个 block 要消耗 4B。这样看来,对于比较大的文件,inode 的空间也是不够用的。因此,当文件的 inode 被写满后,Linux 会自动分配一个 block,这个 block 会像 inode 那样记录其他 block 的信息。通过这种方式,可以把各 block 的内容串联到一起,从而读到完整的文件内容。

        对于存储文件的 block 块,有两种常见情况需要了解:

    • 文件大小不足一个 block 时,也会占用一个 block。譬如大小为 1KB 的文件,也会单独占用一个 block,这里实际浪费了 3KB。

    • 文件大小超过一个 block 时,会占用多个 block。譬如大小为 5KB 的文件,会先用一个完整的 block 存储 4KB,剩下的 1KB 再占用一个 block。

2. Linux 中的链接

        在 Windows 中,快捷方式就是指向原始文件的一个链接文件。一旦原始文件被删除或移动,链接文件就会失效。Linux 系统中的链接比 Windows 复杂,分为硬链接和软链接。

2.1 硬链接(hard link)

        对一个文件而言,其实际内容存储在 block 中,且拥有唯一的 inode。我们可以将硬链接理解为指向这个 inode 的指针,系统并不会为硬链接分配独立的 inode 和 block。因此,硬链接和原始文件其实是同一个文件,只是名字或路径不同。每当我们添加一个硬链接,文件的 inode 连接数都会加一。每当我们删除一个硬链接,文件的 inode 节点数都会减一。只有当一个文件的 inode 连接数为 0 时,才会真正删除它。所以即使我们删掉原始文件,只要还有硬链接指向它,实际文件就不会被删除,我们依然可以通过硬链接来访问它。

        上面的文字解释可能还不够直观,我们再用示意图来阐述。

        譬如我们的磁盘上有一个文件:

        使用 ln fileName newFileName 新建硬链接,示意如下:

        不难看出,现在有了一个名为 fileName 的文件,还有一个 newFileName 的文件。但这两个文件实际指向相同 inode 以及 block。因此,我们修改其中一个文件,另一个文件也会随之改变。这就像编程中的“址传递”。

        接下来我们看看删除操作的影响,这个部分通常会令人困惑。

        删除“原始文件”:

    ​    ​删除硬链接:

    ​    ​PS:其实我认为硬链接这里是没有所谓“原始文件”的概念的。原始文件,也不过是指向这个 inode 的一个硬链接。或者我们可以这样理解,每个文件名其实就是一个硬链接。在 console 中的实验结果也符合这种观点——硬链接的类型也是“-”。

1 kitking@KitkingVM:~/link$ ls -li
2 total 4
3 7879977 -rw-rw-r-- 1 kitking kitking 4 Dec 29 15:18 test.txt
4 kitking@KitkingVM:~/link$ ln test.txt hardlink.txt
5 kitking@KitkingVM:~/link$ ls -li
6 total 8
7 7879977 -rw-rw-r-- 2 kitking kitking 4 Dec 29 15:18 hardlink.txt
8 7879977 -rw-rw-r-- 2 kitking kitking 4 Dec 29 15:18 test.txt

2.2 软链接(symbolic link)

    ​    ​Linux 下的软链接类似 Windows 下的快捷方式,仅包含所链接文件的路径,能够链接目录,也能跨文件系统链接。删除原始文件后,链接文件也将失效。

2.3 新建链接

    ​    ​Linux 的 ln 命令用于创建链接。其常用参数如下:

    • -s:创建软链接(如不加此参数,默认创建硬链接);

    • -f:强制创建文件或目录的链接;

    • -i:覆盖前先询问;

    • -v:显示创建链接的过程。

原文地址:https://www.cnblogs.com/murongmochen/p/14207096.html