inode

在Linux中,文件的元信息被存储在一个 inode 中,inode 中包括除了文件名以外的所有文件信息,可以用stat命令,查看某个文件的 inode 信息,例如

1
stat ~/.bashrc

输出形如

1
2
3
4
5
6
7
8
  File: ‘.bashrc’
Size: 1494 Blocks: 8 IO Block: 4096 regular file
Device: fd02h/64770d Inode: 25774323490 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1004/ user) Gid: ( 1004/ user)
Access: 2023-11-06 19:28:47.327126137 +0800
Modify: 2023-11-06 19:27:47.324249034 +0800
Change: 2023-11-06 19:27:47.345249343 +0800
Birth: -

其中:

  • Inode项是inode编号,这是文件的唯一标识。可以使用ls-i选项查看某个文件的 inode 编号。
  • Links项是硬链接数,对于文件通常都是1,对于目录则会是多个,取决于子文件夹的数目,见下面的内容。

虽然在使用中,用户主要是通过文件名(以及路径)来打开指定的文件,但是实际上,系统内部在操作中会从文件名转换为 inode 编号:

  • 根据文件名,获取对应的 inode 编号
  • 通过 inode 号码,获取 inode 信息
  • 根据 inode 信息,找到文件数据所在的 block,读出数据。

一般情况下,文件名和 inode 编号是一一对应的关系,每个 inode 编号对应一个文件。但是,Linux 系统实际上允许多个文件名指向同一个 inode 编号,这就自然引出了下面的链接的概念。

硬链接

默认情况下,每一个文件名都只是指向对应inode的一个硬链接,此时inode的链接数为1;系统允许让另一个新的文件名也指向同一个inode,就是创建新的硬链接指向已存在的inode,此时inode的链接数+1。

如果两个文件名指向同一个inode,那么用这两个文件名进行的读写操作实际会作用到硬盘中的同一块数据。
对于用户而已,虽然看起来有两个不同的文件,但是修改其中一个文件,会同时影响另一个文件的内容,两者的变化是同步的。

在这种情况下,对文件的删除操作有着不太直观的效果:操作系统首先会将inode的链接数减一,然后检查inode的链接数。
如果链接数变为0,系统会回收这个 inode 编号,以及其所对应的块,但是并没有实际擦除二进制数据,只是将其标记为已经删除,可以重新使用。

换言之,如果一个inode的链接数为n,必须删除所有的硬链接,才能实现真正意义的删除,否则只是去掉了一个硬链接而已。

目录是和文件是不一样的概念:它并不是文件,而是一个列表,包括子文件和子目录。

软链接

创建一个硬链接,就会为文件创建了一个新的文件名。硬链接有两个重要局限性:

硬链接不能链接不在同一系统的文件。也就是说硬链接不能链接与文件不在同一磁盘分区上的文件;
硬链接不能链接目录。
一个硬链接和文件本身没有什么区别。当你列出一个包含硬链接的文件时,不会有特殊的链接指示说明。当一个硬链接被删除时,文件本身的内容仍然存在(也就是说,它所占的磁盘空间不会被重新分配),直到所有关联这个文件的硬链接都删掉。

硬链接和软连接都是文件系统层面的概念,在Windows中也有同样的概念,除此之外,Windows中更常见的快捷方式是由Explorer提供的,效果上和软链接类似,但是从原理上并不一样。

ln 命令

Linux系统具体可以使用ln命令创建硬链接,加上-s选项则会创建软链接(符号链接)。

例如,创建硬链接/path/to/symlink,指向原本的文件/path/to/original/file

1
ln /path/to/original/file /path/to/symlink

创建软件链接/path/to/symlink,指向原本的文件/path/to/original/file

1
ln -s /path/to/original/file /path/to/symlink

对于软链接的访问会直接访问到目标文件,例如使用 vim 打开或修改。对软链接的重命名,得到的结果仍然是一个指向原本目标文件的软链接。
软链接和实际文件的地位是不等价的,对软链接的删除只会删除符号链接自身,不会影响指向的文件。

注:

  • 如果不使用-s选项就会创建硬链接,硬链接的机制和软链接是完全不同的,它和实际文件在文件系统中的地位是等价的,都指向硬盘中的同一个空间,并且硬链接只能用于文件,不能用于目录;
  • 软链接可以指向不存在的文件或目录,如果软链接失效(指向的文件不存在),可能在 ls 命令中显示红色警告;