软链接与硬链接知识点讲解

694 阅读7分钟

前言

因为 pnpm 的原理是利用了硬链接与软链接进行依赖包的管理。本文是简单介绍软链接与硬链接,这将收录进我的专栏 《前端环境搭建与准备-指引》,用以让我的读者更好的了解 pnpm配置

你也可以参考阮一峰的文章深入了解inode 《理解inode》 , 本文仅做简单的介绍。

文件存储

文件储存在硬盘上,硬盘存储中有 inode区数据区

  • 🍋 inode区存储inode节点,inode节点中存储了文件的元数据,元数据信息例如:文件的创建者、文件的创建日期、文件的大小、inode号、IO 块等。
  • 🍋 数据区里以硬盘的最小存储单位扇区(Sector)来存储文件内容,因为一个扇的存储大小(512字节)有限,读取文件时,一次性读取多个扇区(称之为块block)

下图是简化的示意图,用来理解文件存储

(硬盘中的文件存储) image.png

展开来说,以下是一个文件在存储时的示意图如下:

image.png

inode 节点

我们看上图可以知道,inode区里存储着多个inode节点,inode节点里存储文件的元信息,如下示意图:

image.png

其中最重要的是,每个inode节点都有一个inode号用来标识(类似与ID标识),打个比方,inode号就好比身份证号,世界上同名同姓的人太多,但是身份证号是唯一的,在身份信息查询平台输入身份证号就可以读取身份证信息(包括籍贯、性别、出生年月等)。系统读取文件时,首先,系统找到这个文件名对应的inode号码;其次,通过inode号码,获取inode信息;最后,根据inode信息,找到文件数据所在的block,读出数据; 流程简化图如下:

image.png

演示示例

下面我将在windows 10操作系统下使用git bash演示软链接与硬链接的示例 请提前下载git for windows。

🌵预先在E盘中的test文件夹中创建源文件a.txt

image.png

🌵a.txt的内如如下

这是文件的原始内容:
【a.txt是源文件】
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

image.png

软链接(soft link)或"符号链接(symbolic link)

软链接也称之为 "软链接"(soft link)或者"符号链接(symbolic link), 可以点此了解更多的软链接相关介绍:creating-symbolic-links

软链接演示

必须知道的是:git bash创建软链接必须要基于以下2个条件,否则无法正常创建软链接:

  • 使用超管身份运行git bash。
  • 输入命令行运行export MSYS=winsymlinks:nativestrict

我们的目的是创建a.txt的软链接 b.txt

创建软链接

  • 🍀 以超级管理员身份运行git bash,切换到演示示例文件夹。

image.png

cd ../../../e/test
  • 🍀 并输入命令行export MSYS=winsymlinks:nativestrict操作git bash软链(因为软链接类似与windows上的快捷方式,所以以下命令其实是创建快捷方式),因为我电脑暂时没有装虚拟机来模拟Linux系统,只能先暂时这样先。
export MSYS=winsymlinks:nativestrict
  • 🍀 创建a.txt的软链接 b.txt
ln -s a.txt b.txt

image.png

创建完成后,你会发现,在我们的目标演示文件夹中,多了 b.txt文件。并且b.txt文件的文件类型是 .symlink

image.png

我们可以点击看 b.txt的文件内容,可以看到,点击查看 b.txt时,系统自动帮我们把文件指向了a.txt文件。

image.png

ls -li查看文件信息

我们可以使用ls -li 来查看文件信息

image.png

删除软链接的源文件

你可以试着删除 a.txt。你会发现b.txt打不开。或者会提示 "No such file or directory"

软链接特点

我们以这个图来简化软链接存储 image.png

软链接特点有:

  • inode号不同,文件a和文件b的inode号码不同,文件b的内容是文件a的路径
  • 内容相同,无论打开哪一个文件,最终读取的都是文件a
  • 源文件删除,软链无效,如果删除了文件a,无法打开文件b或系统提示报错:"No such file or directory"
  • ⭐允许目录或文件链接,允许在不同的文件系统间进行链接,这两个文件系统可以在同一个计算机上,也可以在不同的计算机上(我们当前没有测试)

简化而言就是:inode号不同,但内容是一样,软链接就相当于源文件的快捷方式,删除源文件,软链无效

硬链接(hard link)

可以点此了解更多的硬链接相关介绍:Hard Links and Junctions

硬链接示例

还是在E盘的test文件夹进行演示,目的是创建 a.txt的硬链接 c.txt

创建硬链接

接着上面的步骤,请确保使用超管身份运行git bash,输入以下命令行

ln a.txt c.txt

可以看到,test文件夹中多了 c.txt

image.png

我们点击进去可以发现,c.txt文件内容和 a.txt文件内容是一模一样的。

image.png

追加硬链接的内容

当我们修改c.txt文件内容,在其后面追加如下内容后保存。

这个是后加的内容

image.png

重新打开 a.txt,你会发现,我们明明没有改变a.txt的文件内容,但是它却和 c.txt文件的内容一模一样,而且修改时间也是一模一样

image.png

image.png

我们运行 ls -i 查看文件inode号。可以发现a.txtc.txt的 inode号是一样的,这个就意味着,它们拥有着同一个inode节点。

image.png

删除硬链接的源文件

当我们删除 源文件 a.txt,并重新打开 c.txt,可以发现, c.txt能正常运行,这是不是意味着c.txt是a.txt的副本呢?但是不完全是,它底层只是做了一硬链接指向同一个inode(当然,同一个inode就表示拥有一样的文件数据),那为什么硬链接似乎与原始链接占用相同的空间?你可以从这里了解:Why do hard links seem to take the same space as the originals?

image.png

尝试跨磁盘创建硬链接

接下来,我们来测试硬链接是否可以跨磁盘,由上,可以知道,当前c.txt文件是在E盘的,我现在在G盘中创建新的文件夹命名为G-test,

image.png

我们的目的是为了创建c.txt的硬链接d.txt到G盘中创建的G-test文件夹,我们输入以下命令行

ln c.txt ../../g/G-test/d.txt

image.png

可以看到,报错了,报错:ln: failed to create hard link '../../g/G-test/d.txt' => 'c.txt': Invalid cross-device link,意思是:不能创建硬链接 ../../g/G-test/d.txt 指向 c.txt,原因是:无效的跨设备链接,由此我们知道,硬链接是不能够跨文件系统的,说白了就是,如果在同一个电脑上就不能跨磁盘创建硬链接。这一点很重要,在我们后续的pnpm配置store存储路径的时候,就需要注意。

硬链接的特点

我们以这个图来简化硬链接存储

image.png

硬链接特点有:

  • inode号相同,内容相同,源文件与目标文件的inode号码相同,都指向同一个inode, 不同的文件名访问同样的内容
  • 修改内容影响全部,对文件内容进行修改,会影响到所有关联的硬链接、软链接(包括源文件)
  • 源文件删除,硬链仍然有效,删除一个文件名,不影响另一个文件名的访问,如果删除了文件a,依然能够打开文件c
  • 不可跨磁盘或文件系统,只能在同一个文件系统范围内进行,不允许跨文件系统或磁盘,只支持文件硬链接,没有目录硬链接。

简化而言就是:inode号相同,内容相同,修改其一的内容,影响全部相关的文件内容,删除源文件,硬链仍然有效,但是不允许跨文件系统创建硬链接