代码之家  ›  专栏  ›  技术社区  ›  Nick Stinemates

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

  •  1050
  • Nick Stinemates  · 技术社区  · 17 年前

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

    23 回复  |  直到 17 年前
        1
  •  691
  •   Loki Astari    17 年前

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

    文件系统中的文件基本上是指向索引节点的链接。
    那么,硬链接只会创建另一个文件,其中包含指向同一底层索引节点的链接。

    当你删除一个文件时,它会删除一个指向底层索引节点的链接。只有当指向索引节点的所有链接都被删除时,索引节点才会被删除(或可删除/可重写)。

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

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

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

        2
  •  395
  •   Adam Matan    12 年前

    俗话说,一图胜千言。以下是我对它的想象:

    enter image description here

    以下是我们如何得到这张图片:

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

      $ echo 'Hello, World!' > myfile.txt
      
    2. 创建硬链接 my-hard-link 到文件 myfile.txt ,这意味着“创建一个应该指向相同索引节点的文件 myfile.txt 指向“:

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

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

    看看现在会发生什么,如果 myfile.txt 被删除(或移动): 我的硬链接 仍然指向相同的内容,因此不受影响,而 我的软链接 现在什么都没有指向。其他答案讨论了每种答案的优缺点。

        3
  •  368
  •   akivajgordon    11 年前

    一些例子可能会有所帮助。

    创建两个包含数据的文件:

    $ 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 =可读、不可写、可执行
        • 其他权限: 卤代烃 =可读、不可写、可执行
      • 硬链接: -rw-r--r--
        • 文件类型: - =常规文件
        • 所有者权限: rw- =可读、可写、不可执行
        • 组权限: r-- =可读、不可写、不可执行
        • 其他权限: r =可读、不可写、不可执行
    • 第二列:硬链接文件的链接数量较高

    • 第5列:软链接的大小较小,因为它是一个参考,而不是副本

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

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

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

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

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

    像foo-Hard这样的硬链接指向文件的索引节点(内容)。

    对于像bar-soft这样的软链接,情况并非如此:

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

    找不到文件的内容,因为软链接指向已更改的名称,而不是内容。

    同样,如果 foo 被删除, foo-hard 仍然持有内容;如果 bar 被删除, bar-soft 只是指向不存在文件的链接。

        4
  •  65
  •   Tanktalus    17 年前

    当原始文件被移动时,硬链接很有用。例如,将文件从/bin移动到/usr/bin或/usr/local/bin。/bin中文件的任何符号链接都会被破坏,但直接指向文件索引节点的硬链接并不重要。

    硬链接可能占用更少的磁盘空间,因为它们只占用一个目录条目,而符号链接需要自己的索引节点来存储它指向的名称。

    硬链接的解析时间也更短——符号链接可以指向符号链接目录中的其他符号链接。其中一些可能在NFS或其他高延迟文件系统上,因此可能会导致网络流量需要解决。硬链接始终位于同一文件系统上,总是在一次查找中解析,并且从不涉及网络延迟(如果它是NFS文件系统上的硬链接,NFS服务器将进行解析,并且客户端系统将看不到它)。有时这很重要。对我来说不是,但我可以想象高性能系统中这可能很重要。

    我还认为,mmap(2)甚至open(2)使用与硬链接相同的功能来保持文件的索引节点处于活动状态,这样即使文件被取消链接(2),索引节点也会保留下来,允许进程继续访问,只有当进程关闭时,文件才会真正消失。这允许更安全的临时文件(如果你可以原子地打开和取消链接,我不记得可能有一个POSIX API,那么你真的有一个安全的临时性文件),在那里你可以读/写数据,而任何人都不能访问它。好吧,在/proc让每个人都能查看你的文件描述符之前,这是真的,但这是另一回事。

    说到这一点,恢复在进程a中打开但在文件系统上未链接的文件,主要是使用硬链接重新创建索引节点链接,这样当打开它的进程关闭或消失时,文件就不会消失。

        5
  •  32
  •   stonk-overflow    9 年前

    软链接 :

    软文件或符号文件更像是原始文件的捷径。…如果您删除了原始快捷方式,则快捷方式将失败,如果您只删除了快捷方式,原始快捷方式将不会发生任何变化。

    软链接语法 : ln -s Pathof_Target_file link

    输出: link -> ./Target_file

    证明: readlink link 也在 ls -l link 输出中,您将看到第一个字母 lrwxrwxrwx 字母 l(英语字母表中的第十二个字母) 这表示该文件是软链接。

    删除链接: unlink link

    注: 如果你愿意,你的软链接即使在从当前目录移动到其他地方后也可以工作。在创建软链接时,确保你给出的是绝对路径,而不是相对路径。即(从/root/user/Target_file开始,而不是./Targetfile)

    硬链接:

    硬链接更多的是镜像副本或同一文件的多个路径。对file1做点什么,它就会出现在文件2中。 删除一个仍然可以保持另一个正常。

    只有当(同一文件)索引节点的所有(硬)链接或所有路径都已删除时,才会删除索引节点(或文件)。

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

    硬链接语法 : ln Target_file link

    输出: 将创建一个具有名称链接的文件,其索引节点号与Targetfile相同。

    证明: ls -i link Target_file (检查它们的索引节点)

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

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

    符号链接具有一些硬链接缺失的功能:

    • 硬链接指向文件内容。而软链接指向 文件名。
    • 而硬链接的大小是内容的大小,而软链接的大小则是 具有文件名大小。
    • 硬链接共享同一个inode。软链接不会。
    • 硬链接不能跨文件系统。软链接可以。
    • 当使用硬链接时,您会立即知道符号链接指向何处 链接,您需要浏览整个文件系统以查找文件 共享同一个inode。

      # find / -inum 517333

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

    硬链接有两个局限性:

    • 目录不能硬链接。Linux不允许这样维护目录的非循环树结构。
    • 无法跨文件系统创建硬链接。这两个文件必须位于同一个文件系统上,因为不同的文件系统具有不同的独立索引节点表(不同文件系统上的两个文件,但具有相同的索引节点号将是不同的)。
        6
  •  29
  •   nobody    12 年前

    通过一个简单的例子,可以看出硬链接和符号链接之间的区别。指向文件的硬链接将指向文件的存储位置或该文件的索引节点。符号链接将指向实际文件本身。

    因此,如果我们有一个名为“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”的任何内容,直到不再有硬链接指向它为止。

        7
  •  29
  •   Prabhat Kumar Singh    7 年前

    符号链接链接到路径名。这可以在系统文件树中的任何位置,甚至在创建链接时都不必存在。目标路径可以是相对路径或绝对路径。

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

        8
  •  19
  •   Jamal Tom_B    10 年前

    我建议你参考维基百科:

    有几点:

    • 与硬链接不同,Symlinks可以跨文件系统(大多数时候)。
    • Symlinks可以指向目录。
    • 硬链接指向一个文件,使您能够用多个名称引用同一个文件。
    • 只要至少有一个链接,数据仍然可用。
        9
  •  8
  •   JesperE    17 年前

    Hard link vs Soft link

    硬链接与软链接可以很容易地通过这张图片来解释。

        10
  •  5
  •   Federico A. Ramponi    17 年前

    执行增量备份时,硬链接非常有用。看见 rsnapshot 例如。这个想法是使用硬链接进行复制:

    • 将备份编号n复制到n+1
    • 将备份n-1复制到n
    • ...
    • 将备份0复制到备份1
    • 用任何更改的文件更新备份0。

    除了您所做的任何更改外,新备份不会占用任何额外空间,因为所有增量备份都将指向未更改文件的同一组索引节点。

        11
  •  3
  •   Amr Mostafa    16 年前

    来自 MSDN ,

    Symbolic link

    符号链接是指向另一个文件系统对象的文件系统对象。被指向的对象称为目标。

    符号链接对用户是透明的;链接显示正常 文件或目录,用户或应用程序可以对其进行操作 以完全相同的方式。

    符号链接旨在帮助迁移和应用 与UNIX操作系统的兼容性。微软已经实施 它的符号链接的功能就像UNIX链接一样。

    符号链接可以是绝对链接,也可以是相对链接。绝对的 链接是指定路径名的每个部分的链接;相对的 链接是相对于relativelink说明符所在的位置来确定的 指定的路径

    绝对符号链接示例

    X: "C:\alpha\beta\absLink\gamma\file"
    Link: "absLink" maps to "\\machineB\share"
    Modified Path: "\\machineB\share\gamma\file"
    

    相对符号链接示例

    X: C:\alpha\beta\link\gamma\file
    Link: "link" maps to "..\..\theta"
    Modified Path: "C:\alpha\beta\..\..\theta\gamma\file"
    Final Path: "C:\theta\gamma\file"
    

    Hard link

    A. 硬链接 是文件的文件系统表示,通过它 多个路径引用单个文件 在同一卷中 .

    要在windows中创建硬链接,请导航到要创建链接的位置,然后输入以下命令:

    mklink /H Link_name target_path
    

    请注意,无论硬链接的创建顺序如何,您都可以按任何顺序删除硬链接。此外,在以下情况下无法创建硬链接

    • 引用位于不同的本地驱动器中
    • 参考文献包括网络驱动器。换句话说,其中一个参考是网络驱动器
    • 要创建的硬链接与目标位于同一路径上

    Junction

    NTFS支持另一种称为连接的链接类型。MSDN对它的定义如下:

    连接(也称为软链接)与硬链接的不同之处在于,它引用的存储对象是单独的目录,连接可以链接位于 同一台计算机上的不同本地卷 否则,交叉口的操作与硬链接相同。

    硬链接部分和连接部分中的粗体部分显示了两者之间的基本区别。

    在窗口中创建连接的命令,导航到要创建链接的位置,然后输入:

    mklink /J link_name target_path
    
        12
  •  3
  •   gnasher729    11 年前

    简单地说,硬链接:就是给一个文件添加新名称,也就是说,一个文件可以同时有多个名称,所有名称都是相等的,没有人喜欢,硬链接的意思不是复制文件的所有内容并制作新文件。不是这样的,它只是创建一个可供选择的名称。。

    符号链接(symlink):是指向另一个文件的文件指针,如果符号链接指向稍后删除的现有文件,则符号链接将继续指向相同的文件名,即使该名称不再命名任何文件。

        13
  •  3
  •   PGOEL    8 年前

    以下答案适用于Web开发人员:

    硬链接:就像将不同的域名指向同一主机

    * abc.com and def.com -> points to the IP 1.2.3.4
    * abc.com and def.com -> files in linux
    * IP -> inode in linux
    * By deleting the domain abc.com users still access your website through def.com or vice versa
    * Mutation through abc.com will affect def.com and vice verca
    

    Sym链接:将一个域重定向到另一个域

    * accessing abc.com will redirect to def.com as you've accessed def.com directly
    * removing the def.com domain will break the link abc.com
    
        14
  •  2
  •   Yassine Abdul-Rahman    13 年前

    也:

    1. 硬链接的读取性能优于符号链接(微观性能)
    2. 符号链接可以复制、版本控制。换句话说,它们是一个实际的文件。另一方面,硬链接的级别稍低,你会发现,与符号链接相比,提供将硬链接作为硬链接而非普通文件使用的工具较少
        15
  •  2
  •   Sнаđошƒаӽ    10 年前

    你所认为的普通“文件”实际上是两个独立的东西:文件的数据和目录条目。当您为文件创建硬链接时,您实际上创建了引用相同数据的第二个目录条目。两个目录条目具有完全相同的功能;每个都可以用来打开文件进行读取。所以你没有真正的“一个文件加一个硬链接”,你有“有两个目录条目的文件数据”。您所认为的删除文件实际上会删除一个目录条目,当删除数据的最后一个目录条目的时候,数据本身也会被删除。对于只有一个目录项的普通文件,删除目录项将一如既往地删除数据。(打开文件时,操作系统会创建一个指向该文件的临时链接,因此即使删除所有目录条目,数据也会保留,但一旦关闭文件就会消失)。

    例如,创建一个文件a.txt、一个硬链接B.txt,然后删除a.txt。创建A.txt时,会创建一些数据和一个目录条目A.txt。当您创建硬链接时,会创建另一个目录条目B.txt,指向完全相同的数据。当你删除A.txt时,你仍然有所有的数据和一个目录条目B.txt,就像你一开始创建了一个文件B.txt一样。

    软链接只是一个(几乎)普通的文件,除了它不包含数据,而是另一个目录条目的路径。如果删除软链接引用的文件,则软链接将包含一个不再指向目录项的路径;它坏了。如果你删除软链接,就像删除任何其他文件一样,它指向的文件不受影响。

        16
  •  2
  •   Draken R. Shilling    10 年前

    目录条目是链接结构:

    struct dentry{
        ino_t ino;
        char  name[256];
    }
    

    inode是inode的数量,name是文件名,inode结构可能如下

    struct inode{
          link_t nlink; 
          ...
    }
    

    例如,您创建了一个文件/1,目录条目可能如下:

    struct dentry{
         ino_t ino; /* such as 15 */
         char  name[256]; /* "1" */
    } 
    

    inode结构可能如下:

       struct inode{ /* inode number 15 */
             link_t nlink; /* nlink = 1 */
             ...
        }
    

    然后你创建一个硬链接(可能是/100),目录条目可能如下:

      struct dentry{
         ino_t ino; /* 15 */
         char  name[256]; /* 100 */
      }
    

    inode结构可能如下:

       struct inode{ /* inode numebr 15 */
             link_t nlink; /* nlink = 2 */
             ...
        }
    

    然后,您创建一个指向文件1的符号链接(可能是/200),目录条目可能如下:

      struct dentry{
            ino_t ino; /* such as 16 */
            char  name[256]; /* "200" */
      }
    

    inode结构可能如下:

       struct inode{ /* inode number 15 */ 
             link_t nlink; /* nlink = 2 */
             ...
        }
    
       struct inode{ /* inode number 16 */
             link_t nlink; /* nlink = 1 */
             ...
        } /* the data of inode 16 maybe /1 or 1 */
    
        17
  •  2
  •   buydadip    9 年前

    我对使用的两点看法:

    柔软的 链接可用于缩短长路径名,即:

    ln -s /long/folder/name/on/long/path/file.txt /short/file.txt
    

    对以下内容所做的更改 /short/file.txt 将应用于原始文件。

    坚固的 链接可用于移动大文件:

    $ ls -lh /myapp/dev/
    total 10G
    -rw-r--r-- 2 root root 10G May 22 12:09 application.bin
    

    ln /myapp/dev/application.bin /myapp/prd/application.bin

    立即复制到不同的文件夹和原始文件(打开 /myapp/dev )可以在不接触文件的情况下移动或删除 /myapp/prd

        18
  •  1
  •   lmmorris1    11 年前

    加上上述所有答案,查找硬链接和软链接文件的差异可以理解如下:

    我有个档案 f6 在我当前的目录中,以及一个名为 t2 .

    文件名 f1 ./t2/f2 是指向的符号链接 f6 .

    文件名 f7 ./t2/f8 是硬链接 f6 .

    要找到软链接和硬链接,我们可以使用:

    $ find -L . -samefile f6 
    
    > ./f1
    > ./f6
    > ./f7
    > ./t2/f2
    > ./t2/f8
    

    要只查找硬链接,我们可以使用:

    $ find . -xdev -samefile f6
    
    > ./f6
    > ./f7
    > ./t2/f8
    

    由于硬链接可以在同一文件系统上创建,因此我们可以搜索所有硬链接,而无需 -L 使用的选项(与 -xdev 选项)位于同一文件系统/挂载点。它将不必要的搜索保存到不同的挂载点。

    因此,搜索硬链接比搜索软链接要快一些(如果我错了或不清楚,请纠正)。

        19
  •  0
  •   themefield Zain Ali    8 年前

    符号链接以类似于硬链接的方式为文件命名。但是,即使有剩余的符号链接,也可以删除文件。

        20
  •  0
  •   s. srinath    8 年前

    我刚刚找到了一种在常见场景(软件安装)中理解硬链接的简单方法。

    有一天,我下载了一个软件到文件夹 Downloads 用于安装。在我做了之后 sudo make install ,一些可执行文件 cp 已发送到本地bin文件夹。在这里, 内容提供商 创建 硬链接 。我对软件很满意,但很快意识到 下载 从长远来看,这不是一个好地方。所以我 mv 已将软件文件夹设置为 source 目录。好吧,我仍然可以像以前一样运行软件,而不用担心任何目标链接的事情,比如在Windows中。这意味着 硬链接 直接查找inode和周围的其他文件。

        21
  •  0
  •   Matheus Santoro    8 年前

    在这个答案中,当我说一个文件时,我指的是内存中的位置

    所有保存的数据都使用名为inode的数据结构存储在内存中。每个inode都有一个inode编号。索引节点号用于访问索引节点。指向文件的所有硬链接可能具有不同的名称,但共享相同的索引节点号。由于所有硬链接具有相同的索引节点号(反过来访问相同的索引点),因此它们都指向相同的物理内存。

    符号链接是一种特殊的文件。由于它也是一个文件,因此它将有一个文件名和一个索引节点号。如上所述,inode编号访问指向数据的inode。现在,符号链接的特殊之处在于,符号链接中的索引节点号访问那些指向另一个文件的“路径”的索引节点。更具体地说,符号链接中的索引节点号会访问指向另一个硬链接的索引节点。

    当我们在GUI中移动、复制、删除文件时,我们是在玩文件的硬链接,而不是物理内存。我们并没有清除物理内存。如果删除了文件的所有硬链接,则无法访问存储的数据,尽管它可能仍存在于内存中

    推荐文章