关于 Linux 中的硬链接你需要知道的一切重要信息
在了解硬链接之前,我建议你先了解一下 Linux 中的 inode。Linux文件系统有两个主要组件:一个用于存储数据的数据块池和一个用于管理此数据池的数据库系统。inode 就像是这个数据库系统的索引。
Linux 中的硬链接是什么?
文件的硬链接指向文件的 inode,而不是指向文件本身。这样硬链接就获得了原始文件的所有属性,并指向与原始文件相同的数据块。
如果您还记得符号链接或软链接,您就会知道它指向文件。硬链接是目录中手动创建的条目,指向已存在的 inode。
我将用适当的图表向您解释。让我们以此目录结构为例:
因此,基本上,根目录包含 dir_1 和 dir_2 目录。dir_1 目录包含 file_1 和 file_2 文件,而 dir_2 包含 file_3 和指向文件 2 的硬链接。
让我们看看文件系统中的情况。一切都是表象。实际上,根目录将有数千个文件。这里,我们假设它只有两个目录。
还记得Linux 目录结构吗?从根目录 (/) 开始。根目录的 inode 始终为 2。
如果您必须访问文件 3,则绝对路径将是 /dir_2/file_3。在这里,您可以这样读取它:从 inode 2 开始(root 始终 indoe 2),然后按照箭头指向其数据块。该数据块包含有关 dir_2 的 inode(在我们的示例中为 inode 27)的信息。
现在查看 inode 27。其类型为目录。您跟踪到其数据块,其中包含有关 file_3 的 inode(inode 88)的信息。您查看 inode 88。其类型为文件,如果您跟踪到其数据块,则可以访问文件的内容。
您是否注意到目录本身并不包含其文件的数据?目录本质上是一个文件,其中包含有关其文件和子目录的 inode 的信息。
您一定想知道上图中的链接数。这非常重要,尤其是在处理硬链接时。链接数是指向 inode 的目录条目数。以 dir_2 的 inode 27 为例。inode 27 一次位于根目录的数据块中,一次位于其自己的数据块(特殊目录 .)中。因此它的链接数为 2。
注意到除了 file_2 之外,所有文件的链接数都是 1 吗?如果某个文件的链接数大于 1,则意味着存在“指向此文件”的硬链接。由于硬链接指向与目标文件相同的 inode(在我们的示例中为 inode 17),因此您会获得 inode 17 的 2 个目录列表(在 dir_1 和 dir_2 的数据块中)。
如何在 Linux 中创建硬链接
您可以使用 ln 命令来创建硬链接:
ln target_file link_name
这将创建一个名为 link_name 的硬链接到 target_file。您将看到 link_name 看起来像一个常规文件,并且其属性与目标文件相同。
如果您使用 ls -li 命令(-i 选项显示 inode 编号),您将看到它的链接数为 2。链接数位于文件权限字段之后。
134195 -rw-r--r-- 2 abhishek abhishek 0 Jul 17 19:49 target_file
134195 -rw-r--r-- 2 abhishek abhishek 0 Jul 17 19:49 link_target_file
显然,两者都具有相同的 inode 编号 134195。
关于硬链接需要注意的事项
现在您对 Linux 中的硬链接已经有了很好的了解,让我们进一步了解一下。
如果目标文件具有硬链接,则删除该文件不会再删除其数据
如果你删除了目标文件,你仍然可以通过硬链接访问其内容。这是因为目标文件和硬链接具有相同的 inode,因此它们指向相同的数据块。
在 Linux 中删除文件基本上就是取消链接。假设您使用 rm 命令删除 file_1。Linux内核将发现 file_1 对应于 inode 16。它将从 dir_1 的列表中删除 file_1 条目,并将 inode 16 的链接数减少 1。现在 inode 16 的链接数为 0,内核知道没有人链接到此 inode,因此可以安全地删除 inode 并删除与其关联的数据块。
现在假设您删除了 file_2。内核将从 dir_1 的列表中删除 file_2,并转到 inode 17。它将减少 inode 17 的链接数,使其降至 1。由于链接数不为零,内核不会删除 inode 或与其关联的数据。因此,如果您访问硬链接,即使原始文件已被删除,您仍然可以访问数据。
您不应该创建指向目录的硬链接
您可以创建指向目录的软链接,但是当您尝试创建指向目录的硬链接时,您会看到如下错误:
ln: newdir/test_dir: hard link not allowed for directory
为什么目录不允许使用硬链接?这是因为使用目录的硬链接可能会破坏文件系统。理论上,您可以使用 -d 或 -F 选项创建目录的硬链接。但大多数 Linux 发行版都不允许这样做,即使您是 root 用户。
几乎不可能区分硬链接和原始文件
让我们再看一下我之前创建的硬链接:
134195 -rw-r--r-- 2 abhishek abhishek 0 Jul 17 19:49 target_file
134195 -rw-r--r-- 2 abhishek abhishek 0 Jul 17 19:49 link_target_file
它们具有相同的属性,但你可以根据上面示例中的名称猜测哪个是链接,但如果名称不明显怎么办?你怎么知道它们的名称是 target_1 和 target_2?
如果文件和链接位于不同的目录中,您可以尝试检查 mtime和其他参数以了解目录内容何时被更改,但即使这样也不确定。如果文件和硬链接位于同一目录中,并且历史记录已被清除,我不确定您如何确定哪个是原始文件,哪个是硬链接。
附加提示:如何找到给定文件的所有硬链接
如果您发现某个文件有多个链接数,您可能会对与其关联的其他硬链接感到好奇。
查找该文件的一个方法是使用文件的 inode 编号。您可以使用命令ls -i
或stat 命令来获取 inode 编号。
一旦获得了 inode 编号,您就可以使用 find 命令查看与其关联的所有链接。
find . -inum inode_number
硬链接很难理解吗?
我希望这篇文章不会太“难”,并且您能更好地理解 Linux 中硬链接的概念。如果您对此主题有疑问或建议,请在下面发表评论。