我知道什么是硬链接,但是为什么要使用它们呢?硬链接的作用是什么?
我知道什么是硬链接,但是为什么要使用它们呢?硬链接的作用是什么?
Answers:
硬链接的主要优点是,与软链接相比,没有大小或速度损失。软链接是普通文件访问之上的一个间接附加层。打开文件时,内核必须取消引用链接,这需要少量时间。该链接还占用磁盘上的少量空间,以保存链接的文本。硬链接不存在这些惩罚,因为它们内置在文件系统的结构中。
我所知道的最好的方式是:
$ ls -id .
1069765 ./
$ mkdir tmp ; cd tmp
$ ls -id ..
1069765 ../
使它的-i
选项为ls
您提供文件的索引节点号。在准备上面示例的系统上,我碰巧位于索引号为1069765的目录中,但是具体值无关紧要。它只是标识特定文件/目录的唯一值。
这就是说,当我们进入子目录并查看另一个名为的文件系统条目时..
,它具有与之前相同的inode编号。这不会发生,因为外壳程序正在..
为您解释,就像MS-DOS和Windows一样。在Unix文件系统上,..
是一个真实的目录条目。这是指向先前目录的硬链接。
硬链接是将文件系统目录捆绑在一起的腱。从前,Unix没有硬链接。添加它们是为了将Unix的原始平面文件系统转变为分层文件系统。
(有关此内容的更多信息,请参见为什么'/'具有'..'条目?。)
在Unix系统上,由同一可执行文件实现几个不同的命令在某种程度上也很常见。它似乎并没有在Linux上的任何更多的情况,但在系统我在过去使用cp
,mv
并且rm
都是相同的可执行文件。如果您考虑一下,这是有道理的:在卷之间移动文件时,它实际上是一个副本,之后是一个删除,因此mv
已经必须实现其他两个命令的功能。可执行文件可以弄清楚要提供的操作,因为它传递了调用它的名称。
嵌入式Linux中常见的另一个示例是BusyBox,它是一个实现数十个命令的单个可执行文件。
我应该指出,在大多数文件系统上,不允许用户建立目录的硬链接。的.
和..
条目自动地由文件系统代码,通常是内核的一部分进行管理。存在此限制是因为如果您不小心如何创建和使用目录硬链接,则可能导致严重的文件系统问题。这是存在软链接的众多原因之一。他们承担的风险不一样。
如果在阅读了该维基百科页面之后,您的问题是“我为什么会使用它们”,那么您不了解什么是硬链接。
一个链接是指向磁盘块的目录条目。换句话说,系统上的每个文件都至少具有一个链接。当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
您可以看到bunzip2
,bzcat
并且bzip
全部使用相同的inode。本质上,它是一个具有三个名称的文件。您可以拥有该文件的三个副本,但是为什么呢?它只会浪费不必要的磁盘空间。
/bin
,我想这是造成混淆的原因之一。为什么有时可执行文件会被符号链接,有时会被硬链接?
我可能应该介绍硬链接的一个陷阱。只要原始链接文件存在,硬链接就是具有不同名称和/或不同位置的同一文件。将文件视为“原始”文件甚至是不正确的:它们本身都是目录条目,并且两个(或多个)都是同等的。对于寿命很长的文件,这可能是件好事,但是如果删除并创建一对文件,即使名称和内容相同,文件也会分开。
假设您创建了一个/foo/myfile
链接到的硬链接/repo/myfile
。两者都是指向相同文件数据的指针。改变一个,另一个改变。但是,假设/repo
恰好拥有一个Git存储库。如果签出不包含myfile
在其中的分支,则将其/repo/myfile
删除。此时,/foo/myfile
成为的简单副本/repo/myfile
,就像这对中的另一个未链接时一样。在文件目录更改的分支之间切换时,甚至不容易注意到,但是当您签出原始分支时,会发现一个新文件/repo/myfile
由Git创建。如果您不注意,您会想知道为什么这两个文件现在具有不同的内容,尽管很容易搞怪,因为文件之间的硬链接关系并不知道它们的名称。相反,软链接将在此删除-创建周期中保留下来。
另一方面,使用硬链接的软件会敏锐地意识到这一点,Git是一个很好的例子。Git几乎免费地在同一文件系统上克隆存储库,因为默认情况下它使用硬链接而不是复制文件。对于Git来说,硬链接是一个完美的用例,因为它的对象和打包文件永远不会更改,因此存储库的一个克隆永远不会修改另一个(Git知道不对可修改文件进行硬链接),并且任何克隆都可以在没有任何预防措施的情况下将其删除:无需跟踪哪个文件是“原始文件”并实际包含文件:任何硬链接都是同等伙伴,并且“包含”整个文件。软链接在这里不起作用。
硬链接的另一个优点是,可以移动任何链接而不会中断对文件内容的访问。使用软链接,移动原始文件将使其悬空到其的所有软链接。
最重要的是,在许多用例中,任何一种链接类型都可以很好地工作,但是在某些情况下,另一种类型是有利的。在这里的许多答案中提到的效率,对于现代机器和文件系统可能几乎没有什么关系,除非您在微弱的嵌入式控制器的FLASH芯片上清除文件系统。在功能上的差异更为重要,通常决定了工程约束和最终的选择:
另外,我必须指出,删除文件的库调用是unlink()
有原因的!每个目录条目只是一个最初指向其索引节点的硬链接。