符号链接和硬链接有什么区别?

1068

最近在一次工作面试中,我被问到了这个问题。我很诚实地回答说,我知道符号链接的行为方式以及如何创建它,但是不理解硬链接的用途以及与符号链接的区别。


4
“不理解硬链接的用途”的意思是,在构建系统中,如果需要频繁地复制二进制文件,则可以使用硬链接。创建硬链接可以加快速度,而无需实际复制文件。MSBuild 4.0 支持此功能。 - Ankush
20
我认为这个链接非常有用,可以帮助理解。http://askubuntu.com/questions/108771/what-is-the-difference-between-a-hard-link-and-a-symbolic-link - kta
3
unix.stackexchange提供了一个很好的条目列表,非常有帮助,因为它将所有限制都简洁地列出来,易于浏览。 (这些项目中的许多涵盖了仅在此问题的评论中提到或根本未提到的边缘情况/警告) - Trevor Boyd Smith
1
https://www.youtube.com/watch?v=lW_V8oFxQgA - Ahmed Nabil
23个回答

1050

在文件系统的下层,文件是由索引节点(inode)表示的。(或者说是由多个inode表示?不确定。)

文件系统中的文件基本上是指向一个inode的链接。
硬链接(hard link)会创建另一个文件,并链接到相同的基础inode。

当你删除一个文件时,它会删除对基础inode的一个链接。只有当所有对inode的链接都被删除时,inode才会被删除(或可删除/覆盖)。

符号链接是指向文件系统中另一个名称的链接。

一旦创建了硬链接,它链接的是inode。删除、重命名或移动原始文件不会影响硬链接,因为它链接到基础inode。对inode上的数据所做的任何更改都会反映在引用该inode的所有文件中。

注意:硬链接仅在同一文件系统内有效。符号链接可以跨文件系统,因为它们只是另一个文件的名称。


102
你可能希望添加一个有用的功能,即符号链接可以跨越文件系统,而硬链接不能(它们必须引用同一文件系统上的文件)。 - paxdiablo
73
在Linux Gazette的一篇文章中有一个很好的视觉解释。 - Rodrigue
2
@Zen:你有一个根目录。但是你可以在树的任何地方挂载文件系统。每个分区都有自己的文件系统,你甚至可以使用nfs等方式挂载其他机器上的文件系统... - Martin York
2
@zen:我不喜欢你的DNS示例,因为它添加了太多其他层次的间接性,并且取决于你如何解释这些层次。 就个人而言,我将所有DNS都视为软链接的示例(如果我将www.c.com从10.10.10.10更改为10.10.10.11,则仍然可以提供文件,但它与原始文件不同。硬链接是指向inode的链接,因此明确指向数据。无论对文件进行何种操作,文件始终指向相同的inode,因此指向相同的数据。 - Martin York
2
@ThunderWiring:符号链接(软链接)是从一个文件名到另一个文件名的链接。当您打开符号链接时,文件系统会沿着链接链跟踪,直到它到达真实文件。然后,它使用真实文件来访问底层iNode数据。命令readlink -f <fileName>将跟随符号链到真实文件。 - Martin York
显示剩余17条评论

746

俗话说得好,一张图片胜过千言万语。我是这样想象的:

输入图像描述

下面是如何得到这张图片的过程:

  1. 在文件系统中创建名为 myfile.txt 的文件,该文件指向一个新的 inode(其中包含文件的元数据,并指向包含其内容的数据块,即文本“Hello, World!”):

    $ echo 'Hello, World!' > myfile.txt
    
  2. 创建一个硬链接my-hard-link到文件myfile.txt,意思是"创建一个文件,它应该指向与myfile.txt指向相同的inode":

  3. $ ln myfile.txt my-hard-link
    
  4. 创建一个软链接my-soft-link指向文件myfile.txt,意思是“创建一个文件,该文件应指向文件myfile.txt”:

  5. $ ln -s myfile.txt my-soft-link
    

如果删除(或移动)myfile.txt,现在会发生什么: my-hard-link 仍然指向相同的内容,因此不受影响,而 my-soft-link 现在指向空。其他答案讨论了每个链接类型的优缺点。


6
@ThunderWiring 在这里的“point”指的是链接引用的内容。对于硬链接,它直接引用inode(即myfile.txt所引用的相同inode)。而对于符号链接,它的引用不是inode(inode包含数据),而是文件系统路径到myfile.txt(例如/home/Documents/myfile.txt)。 - akivajgordon
54
也许我有点迟钝,但你的图片在两秒钟内解开了20年的谜团。 - SO_fix_the_vote_sorting_bug
8
非常实用的答案,可惜深埋在这篇帖子中。我想给你100个网络积分,但遗憾的是我只能给你一个。 - Dagrooms
8
是的,我是在Keynote中亲自制作了那个可视化图表。那篇文章的作者只是复制了这张图片。此外,那篇文章是在2017年发表的,而我的回答是在2015年发表的。 - akivajgordon
4
可能是最好的解释,这个答案应该被接受。 - Dashrath Mundkar
显示剩余6条评论

608

以下是一些可能有帮助的例子。

创建两个文件,并在其中填充数据:

$ printf Cat > foo
$ printf Dog > bar
创建一个硬链接和软链接(也称为符号链接):
$ ln foo foo-hard
$ ln -s bar bar-soft

按大小升序列出长格式的目录内容:

ls -lrS
lrwxr-xr-x   1 user  staff        3  3 Apr 15:25 bar-soft -> bar
-rw-r--r--   2 user  staff        4  3 Apr 15:25 foo-hard
-rw-r--r--   2 user  staff        4  3 Apr 15:25 foo
-rw-r--r--   1 user  staff        4  3 Apr 15:25 bar

这告诉我们:

  • 第一个列:软链接和硬链接的文件模式不同

    • 软链接:lrwxr-xr-x
      • 文件类型: l = 符号链接
      • 所有者权限:rwx = 可读,可写,可执行
      • 组权限:r-x = 可读,不可写,可执行
      • 其他用户权限:r-x = 可读,不可写,可执行
    • 硬链接:-rw-r--r--
      • 文件类型:- = 普通文件
      • 所有者权限:rw- = 可读,可写,不可执行
      • 组权限:r-- = 可读,不可写,不可执行
      • 其他用户权限:r-- = 可读,不可写,不可执行
  • 第二个列:硬链接文件的链接数更高

  • 第五个列:软链接的大小更小,因为它是引用而不是副本

  • 最后一列:符号链接通过 -> 显示其链接到的文件

更改 foo 的文件名不会影响 foo-hard。

$ mv foo foo-new
$ cat foo-hard
Cat

修改foo的内容会反映在foo-hard中:

$ printf Dog >> foo
$ cat foo-hard
CatDog

像 foo-hard 这样的硬链接指向文件的inode节点,即文件的内容。

而对于 bar-soft 这样的软链接,则不是这种情况:

$ mv bar bar-new
$ ls bar-soft
bar-soft
$ cat bar-soft  
cat: bar-soft: No such file or directory

由于软链接指向的是名称而非内容,因此找不到该文件的内容。

同样地,如果删除了foofoo-hard仍然保存着内容;如果删除了barbar-soft只是指向一个不存在的文件的链接。


22
这是否意味着“文件”和“硬链接”是相同的,都指向一个inode?删除文件或硬链接时,只要有一个仍然指向该inode,内容就仍然存在,对吗? - Daniel W.
6
正确。只要至少有一个硬链接(即文件)指向它,内容就是可访问的。 - Adam Matan
6
touch blah1; touch blah2 can be shortened to touch blah1 blah2 - Dmitri Zaitsev
15
@DmitriZaitsev 确实如此,但在我看来对于初学者来说可读性会降低。 - Adam Matan
15
我认为这是我读过的许多答案中最易理解的答案。一个样例胜过一大堆解释文字。 - Scott Chu
显示剩余2条评论

84
硬链接在原始文件移动时非常有用,例如从/bin移动到/usr/bin或/usr/local/bin。任何指向/bin中的文件的符号链接都会因此而中断,但硬链接直接链接到文件的inode,不会受到影响。
硬链接可能占用更少的磁盘空间,因为它们只占用目录条目,而符号链接需要自己的inode来存储它指向的名称。
硬链接解析起来也更快 - 符号链接可以指向在符号链接目录中的其他符号链接。其中一些可能在NFS或其他高延迟的文件系统上,因此可能会产生网络流量以进行解析。硬链接始终位于同一文件系统上,总是在单次查找中解析,并且从不涉及网络延迟(如果是NFS文件系统上的硬链接,则NFS服务器将进行解析,对客户端系统不可见)。有时这很重要。虽然对我来说不重要,但我可以想象在高性能系统中这可能很重要。
我还认为诸如mmap(2)甚至open(2)使用与硬链接相同的功能来保持文件的inode处于活动状态,这样即使文件被unlink(2),inode仍然存在,以允许进程继续访问,直到进程关闭它才会真正消失。这允许更安全的临时文件(如果您可以使打开和解除链接同时发生,可能有一个POSIX API来实现这一点,然后您确实拥有一个安全的临时文件),在其中您可以读/写数据而没有人能够访问它。好吧,那是在/proc赋予每个人查看您文件描述符的能力之前的事情,但这是另一个故事。
说到这里,恢复在进程A中打开但在文件系统上被取消链接的文件涉及使用硬链接重新创建inode链接,以便文件在具有打开文件的进程关闭它或消失时不会消失。

48

软链接:

软链接或者符号链接更多地是原文件的快捷方式,如果你删除了原文件,快捷方式也会失效,而如果你只删除了快捷方式,则不会对原文件产生任何影响。

软链接语法:ln -s 被链接文件路径 链接名称

输出:链接名称 -> ./被链接文件

验证:readlink 链接名称 ,另外在ls -l 链接名称 的输出中你将会看到lrwxrwxrwx的第一个字母为l,这表明该文件是一个软链接。

删除链接:unlink 链接名称

注意:如果希望软链接即使在当前目录下移动后仍然可以工作,确保在创建软链接时使用绝对路径而不是相对路径,即从 /root/user/Target_file 开始而不是./Target_file

硬链接:

硬链接更多地是镜像副本或指向同一文件的多个路径。对文件1进行操作后,它将出现在文件2中,删除一个链接仍然会保留另一个链接。

只有在所有的(硬)链接或指向相同文件的所有路径被删除后,inode(或文件)才会被删除。

一旦创建了硬链接,该链接具有原始文件的inode。删除、重命名或移动原始文件都不会影响硬链接,因为它链接到底层inode。对inode上的数据所做的任何更改都会反映在引用该inode的所有文件中。

硬链接语法:ln 被链接文件 链接名称

输出:将创建一个名为链接名称的文件,其inode号与Targetfile相同。

验证:ls -i 链接名称 Target_file (检查它们的inode)

删除链接:rm -f 链接名称 (像普通文件一样删除链接)

注意:符号链接可以跨越文件系统,因为它们只是另一个文件的名称。而硬链接仅在同一个文件系统内有效。

符号链接比硬链接多了一些功能:

  • 硬链接指向文件内容,而软链接指向文件名。
  • 硬链接的大小是内容的大小,而软链接的大小是文件名的大小。
  • 硬链接共享相同的inode,而软链接则没有。
  • 硬链接不能跨越文件系统,而软链接可以。
  • 使用符号链接时,你可以立即知道它指向哪里,而对于硬链接,你需要探索整个文件系统才能找到共享相同inode的文件。

    # find / -inum 517333

/home/bobbin/sync.sh
/root/synchro
  • 硬链接不能指向目录。

  • 硬链接有两个限制:

    • 不能对目录进行硬链接。Linux不允许这样做是为了维护目录的非循环树结构。
    • 不能在不同的文件系统之间创建硬链接。两个文件必须在同一文件系统上,因为不同的文件系统具有不同独立的inode表格(两个在不同文件系统上但inode编号相同的文件将是不同的)。

    3
    硬链接的大小等同于内容的大小,而软链接的大小只有文件名大小。只是为了澄清:创建另一个硬链接只会影响几个字节的可用空间。 - Ingo

    47

    理解硬链接和符号链接之间的区别的简单方法是通过一个简单的例子。硬链接指向文件存储的位置,或该文件的索引节点(inode)。而符号链接将指向实际文件本身。

    因此,如果我们有一个名为“a”的文件,并创建一个硬链接“b”和一个符号链接“c”,它们都将引用文件“a”:

    echo "111" > a
    ln a b
    ln -s a c
    

    "a", "b", 和 "c" 的输出为:

    cat a --> 111
    cat b --> 111
    cat c --> 111
    

    现在让我们删除文件"a",看看输出的"a"、"b"和"c"会发生什么:

    rm a
    cat a --> No such file or directory
    cat b --> 111
    cat c --> No such file or directory
    

    发生了什么?

    因为文件"c"指向文件"a"本身,如果文件"a"被删除,那么文件"c"将没有指向任何东西,实际上它也被删除了。

    然而,文件"b"指向存储位置或文件"a"的索引节点。因此,如果文件"a"被删除,则不再指向该索引节点,但是由于文件"b"指向它,该索引节点将继续存储原先属于"a"的所有内容,直到没有更多的硬链接指向它为止。


    可能有必要指出,文件是一个非常抽象的对象,像所有抽象的东西一样,高级实现的真正意图可能会缺乏适当的解释,而不会冒险破坏抽象性。 - Cholthi Paul Ttiopic
    硬链接比符号链接慢吗?由于硬链接的工作方式类似于复制。 - Muhammad Ikhwan Perwira

    33

    符号链接指向一个路径名,它可以位于系统文件树的任何位置,甚至在创建链接时可能并不存在。目标路径可以是相对路径或绝对路径。

    硬链接是对inode的附加指针,这意味着它们只能存在于与目标相同的卷上。对文件的其他硬链接与用于引用文件的“原始”名称无法区分。


    1
    此外,当您删除所链接的文件时,符号链接将被打破,而硬链接仍然有效,因为它会在文件系统中“保留”文件。 - njsf

    23

    我会向您指引维基百科:

    几点需要注意:

    • 符号链接(symlinks)可以跨越文件系统(在大多数情况下)。
    • 符号链接可以指向目录。
    • 硬链接指向一个文件,并使您能够使用多个名称引用同一文件。
    • 只要还有至少一个链接,数据仍然可用。

    3
    理论上(在某些情况下甚至在实践中)硬链接也可以指向目录(事实上,"." 是当前目录的硬链接,".." 是父目录的硬链接)。但是它们可能会带来危险,所以大多数UNIX系统不允许使用它们(或者要求您采取特殊步骤来使用)。例如,苹果公司在他们的时间机器实现中使用了它们:http://earthlingsoft.net/ssp/blog/2008/03/x5_time_machine - Joachim Sauer
    4
    你指向了一篇文章的链接...这是否意味着你成为了一个符号链接? - Ian Campbell
    @JoachimSauer,您认为新的苹果文件系统是否会消除Time Machine使用硬链接到目录的需要? - cjm
    我发现维基百科的解释比最佳答案中的解释更为简短和具体。 - Evgenia Karunus

    12

    硬链接与软链接的区别

    通过这张图片,可以轻松地解释硬链接和软链接之间的区别。


    6
    我猜测你的软链接图片不正确。要点:软链接的 inode 不应该指向原始文件的 inode。因为如果你重命名了原始文件,相关的软链接就会失效。 - percy507
    @percy507 是的,你说得对 - 但我仍然觉得这是一个非常好的和直观的解释。想象一下,在索引节点之间没有箭头... - Michael Litvin

    9
    硬链接在进行增量备份时非常有用。例如,可以查看rsnapshot。其思想是使用硬链接进行复制:
    • 将备份号码n复制到n+1
    • 将备份n-1复制到n
    • ...
    • 将备份0复制到备份1
    • 更新备份0中的任何更改文件。
    新备份除了您所做的更改外不会占用任何额外的空间,因为所有增量备份都将指向未更改的文件的相同inode集合。

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接