为什么存在硬链接?


Answers:


56

硬链接的主要优点是,与软链接相比,没有大小或速度损失。软链接是普通文件访问之上的一个间接附加层。打开文件时,内核必须取消引用链接,这需要少量时间。该链接还占用磁盘上的少量空间,以保存链接的文本。硬链接不存在这些惩罚,因为它们内置在文件系统的结构中。

我所知道的最好的方式是:

$ ls -id .
1069765 ./
$ mkdir tmp ; cd tmp
$ ls -id ..
1069765 ../

使它的-i选项为ls您提供文件的索引节点号。在准备上面示例的系统上,我碰巧位于索引号为1069765的目录中,但是具体值无关紧要。它只是标识特定文件/目录的唯一值。

这就是说,当我们进入子目录并查看另一个名为的文件系统条目时..,它具有与之前相同的inode编号。这不会发生,因为外壳程序正在..为您解释,就像MS-DOS和Windows一样。在Unix文件系统上,..是一个真实的目录条目。这是指向先前目录的硬链接。

硬链接是将文件系统目录捆绑在一起的腱。从前,Unix没有硬链接。添加它们是为了将Unix的原始平面文件系统转变为分层文件系统。

(有关此内容的更多信息,请参见为什么'/'具有'..'条目?。)

在Unix系统上,由同一可执行文件实现几个不同的命令在某种程度上也很常见。它似乎并没有在Linux上的任何更多的情况,但在系统我在过去使用cpmv并且rm都是相同的可执行文件。如果您考虑一下,这是有道理的:在卷之间移动文件时,它实际上是一个副本,之后是一个删除,因此mv已经必须实现其他两个命令的功能。可执行文件可以弄清楚要提供的操作,因为它传递了调用它的名称。

嵌入式Linux中常见的另一个示例是BusyBox,它是一个实现数十个命令的单个可执行文件。

我应该指出,在大多数文件系统上,不允许用户建立目录的硬链接。的...条目自动地由文件系统代码,通常是内核的一部分进行管理。存在此限制是因为如果您不小心如何创建和使用目录硬链接,则可能导致严重的文件系统问题。这是存在软链接的众多原因之一。他们承担的风险不一样。


4
关于“链接还占用磁盘上的少量空间来保存链接的文本。” 在现代文件系统上,因为目录条目本身就是用来存储链接路径的,所以没有多余的空间用于存储链接路径,至少在名称不能容纳得太长的情况下如此。这称为“快速符号链接”
jlliagre

我要补充一点,有些应用程序不知道如何处理软(符号)链接,因此,当通过引用相同的数据/配置文件配置硬链接时,硬链接可能有助于避免冗余。ioquake3是一个示例,它不能遵循符号链接的pk3文件,但可以遵循硬链接的pk3文件。
令人惊讶的2014年

3
另外,如果删除符号链接的目标,则文件将消失并且符号链接会损坏。硬链接不存在的问题。
频谱

1
但是硬链接也包含一些信息-它们的名称。因此,它应该占用空间。
约瑟夫·克利穆克

39

硬链接的一种非常有用的用法是与rsync结合使用的增量备份。这样可以节省大量空间,并使恢复过程非常容易。我使用这种方法在服务器中进行备份。

请花一些时间阅读此说明


12

如果在阅读了该维基百科页面之后,您的问题是“我为什么会使用它们”,那么您不了解什么是硬链接。

一个链接是指向磁盘块的目录条目。换句话说,系统上的每个文件都至少具有一个链接。当rm一个文件的实际系统调用unlink()。它删除目录条目。磁盘上的块没有更改,但是链接消失了,因此文件从目录列表中消失了。

您个人可能永远不会使用硬链接,但它们遍布您的系统。例如:

$ ls -li /bin | grep 53119771
53119771 -rwxr-xr-x 3 root root  26292 2010-08-18 10:15 bunzip2
53119771 -rwxr-xr-x 3 root root  26292 2010-08-18 10:15 bzcat
53119771 -rwxr-xr-x 3 root root  26292 2010-08-18 10:15 bzip2

您可以看到bunzip2bzcat并且bzip全部使用相同的inode。本质上,它是一个具有三个名称的文件。您可以拥有该文件的三个副本,但是为什么呢?它只会浪费不必要的磁盘空间。


12
但在中也有许多符号链接/bin,我想这是造成混淆的原因之一。为什么有时可执行文件会被符号链接,有时会被硬链接?
Dmitry Pashkevich 2013年

16
此答案根本无法提供任何在软链接上使用硬链接的原因。
马克·阿默里

8

有许多用途。我用它们来创建基于文件的锁。与大多数其他系统调用不同,link(2)系统调用是原子的。

rsnapshot的另一用途是使用硬链接来减少磁盘空间量,从而随时间进行备份。如果文件未更改,则将文件硬链接到文件的较旧实例,然后将已更改的文件重新复制。

我还使用它们来交换服务器上的配置文件:rm file.cfg && ln ~/tmp/file.cfg file.cfg,然后可以安全地删除〜/ tmp / *文件。


1
为什么要分开lnrm不是一个mv
Tommiie

6

为了增加已经存在的几个好的讨论...

  • 在Unix中实现程序资源访问的方式(即“一切都是文件”),这意味着OS完全需要用于处理对文件的多个引用的基础结构,因此这里没有增加成本。
  • 该方式的目录是在原来的Unix文件系统实现(即一个固定的格式列表(inode, name)对意味着是在文件系统中无需额外支付费用有硬链接(当然,只要我们避免周期比不允许hardlinke目录(而其他...(这开始让其他任何人都感觉不舒服吗?))

因此我们免费获得它们。


2

我可能应该介绍硬链接的一个陷阱只要原始链接文件存在,硬链接就是具有不同名称和/或不同位置的同一文件。将文件视为“原始”文件甚至是不正确的:它们本身都是目录条目,并且两个(或多个)都是同等的。对于寿命很长的文件,这可能是件好事,但是如果删除并创建一对文件,即使名称和内容相同,文件也会分开。

假设您创建了一个/foo/myfile链接到的硬链接/repo/myfile。两者都是指向相同文件数据的指针。改变一个,另一个改变。但是,假设/repo恰好拥有一个Git存储库。如果签出不包含myfile在其中的分支,则将其/repo/myfile删除。此时,/foo/myfile成为的简单副本/repo/myfile,就像这对中的另一个未链接时一样。在文件目录更改的分支之间切换时,甚至不容易注意到,但是当您签出原始分支时,会发现一个文件/repo/myfile由Git创建。如果您不注意,您会想知道为什么这两个文件现在具有不同的内容,尽管很容易搞怪,因为文件之间的硬链接关系并不知道它们的名称。相反,软链接将在此删除-创建周期中保留下来。

另一方面,使用硬链接的软件会敏锐地意识到这一点,Git是一个很好的例子。Git几乎免费地在同一文件系统上克隆存储库,因为默认情况下它使用硬链接而不是复制文件。对于Git来说,硬链接是一个完美的用例,因为它的对象和打包文件永远不会更改,因此存储库的一个克隆永远不会修改另一个(Git知道不对可修改文件进行硬链接),并且任何克隆都可以在没有任何预防措施的情况下将其删除:无需跟踪哪个文件是“原始文件”并实际包含文件:任何硬链接都是同等伙伴,并且“包含”整个文件。软链接在这里不起作用。

硬链接的另一个优点是,可以移动任何链接而不会中断对文件内容的访问。使用软链接,移动原始文件将使其悬空到其的所有软链接。

最重要的是,在许多用例中,任何一种链接类型都可以很好地工作,但是在某些情况下,另一种类型是有利的。在这里的许多答案中提到的效率,对于现代机器和文件系统可能几乎没有什么关系,除非您在微弱的嵌入式控制器的FLASH芯片上清除文件系统。在功能上的差异更为重要,通常决定了工程约束和最终的选择:

  • 硬链接“源”可以安全地移动,而软链接将断开。
  • 硬链接与从其链接的文件是无法区分的,只要任何硬链接都处于活动状态,该文件就处于活动状态。软链接是不对称的。
  • 如果删除并重新创建,则硬链接的对等方会脱离链接组,但软链接不会丢失其目标。
  • 软链接可能会跨文件系统,而硬链接则不能。
  • 软链接可能指向目录,而硬链接通常不能(实际上通常不应该)。

另外,我必须指出,删除文件的库调用是unlink()有原因的!每个目录条目只是一个最初指向其索引节点的硬链接。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.