关于 Linux 中的硬链接你需要知道的所有重要信息

在你看到硬链接之前,我建议你了解 Linux 中的 inode。 Linux 文件系统有两个主要组件:存储数据的数据块池和管理该数据池的数据库系统。 inode 就像这个数据库系统的索引。

指向文件的硬链接指向文件的 inode,而不是指向文件本身。 这样硬链接获取了原文件的所有属性,并指向与原文件相同的数据块。

如果你记得符号链接或软链接,你就知道它指向文件。 硬链接是在目录中手动创建的条目,指向一个已经存在的 inode。

我将用适当的图表向您解释。 让我们把这个目录结构 example:

文件系统表示

所以基本上,根目录包含 dir_1 和 dir_2 目录。 dir_1 目录包含 file_1 和 file_2 文件,而 dir_2 包含 file_3 和指向文件 2 的硬链接。

让我们看看文件系统中的情况。 一切都是有代表性的。 实际上,根目录将有数千个文件。 在这里,我们假设它只有两个目录。

Inode Linux 文件系统

还记得 Linux 目录结构吗? 您从根 (/) 开始。 根目录总是有 inode 2。

如果必须访问文件 3,则绝对路径为 /dir_2/file_3。 在这里,您可以这样阅读:您从 inode 2 开始(root 总是 indoe 2),然后按照箭头指向它的数据块。 这个数据块有关于 dir_2 的 inode 的信息(我们的 inode 27 example)。

现在查看inode 27。它的类型是目录。 您跟随它的数据块,其中包含有关 file_3 的 inode 的信息(inode 88)。 你查看inode 88。它的类型是文件,如果你跟随它的数据块,你就可以访问文件的内容。

您是否注意到目录本身并不满足其文件数据? 目录本质上是一个文件,其中包含有关其文件和子目录的 inode 的信息。

您一定想知道上图中的链接计数。 这在处理硬链接时特别重要。 链接计数是指向 inode 的目录条目数。 取 inode 27 为 dir_2 为 example. inode 27 一次在根目录的数据块中,一次在它自己的数据块(特殊目录.)中。 因此它的链接数为 2。

请注意,除了 file_2 之外,所有文件的链接计数都为 1? 如果文件的链接计数超过 1,则表示存在“到此文件”的硬链接。 由于硬链接指向同一个 inode(我们的 inode 17 example) 作为目标文件,您将获得 inode 17 的 2 个目录列表(在 dir_1 和 dir_2 的数据块中)。

您可以使用 ln 命令来创建硬链接:

ln target_file link_name

这将为 target_file 创建一个名为 link_name 的硬链接。 您会看到 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中的硬链接

现在您对 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 选项创建指向目录的硬链接。 但即使您是 root 用户,大多数 Linux 发行版也不允许这样做。

让我们再看一下我之前创建的硬链接:

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

它们具有相同的属性,但您可以根据上面的名称猜出哪个是链接 example 但是如果名字不明显怎么办? 你怎么知道他们的名字是 target_1 还是 target_2?

如果文件和链接位于不同的目录中,您可以尝试检查 mtime 和其他参数以了解目录内容何时更改,但即使这样也不确定。 如果文件和硬链接在同一目录中并且历史记录已被清除,我不确定您如何确定哪个是原始文件,哪个是硬链接。

如果您看到一个文件有多个链接计数,您可能会对与之关联的其他硬链接感到好奇。

一种查找方法是使用文件的 inode 编号。 您可以使用 ls -i 命令或 stat 命令来获取 inode 编号。

获得 inode 编号后,您可以使用 find 命令查看与其关联的所有链接。

find . -inum inode_number

很难理解硬链接吗?

我希望这不是太“难”,并且您对 Linux 中硬链接的概念有更好的理解。 如果您对此主题有疑问或建议,请在下面发表评论。