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

Unix 符号链接和硬链接之间有什么区别?,unix,symlink,hardlink,Unix,Symlink,Hardlink,最近我在一次工作面试中被问到这个问题。我说实话,我知道符号链接的行为以及如何创建符号链接,但不了解硬链接的用法以及它与符号链接的区别。在文件系统下面,文件由inode表示。(或者是多个索引节点?不确定。) 文件系统中的文件基本上是指向inode的链接。 然后,硬链接只是创建另一个文件,其中包含指向同一基础inode的链接 删除文件时,会删除一个指向基础inode的链接。只有当指向inode的所有链接都已删除时,才会删除该inode(或可删除/可重写) 符号链接是指向文件系统中其他名称的链接 一旦

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

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

文件系统中的文件基本上是指向inode的链接。
然后,硬链接只是创建另一个文件,其中包含指向同一基础inode的链接

删除文件时,会删除一个指向基础inode的链接。只有当指向inode的所有链接都已删除时,才会删除该inode(或可删除/可重写)

符号链接是指向文件系统中其他名称的链接

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


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

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


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

我想让您看看维基百科:

有几点:

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

我补充尼克的问题:硬链接什么时候有用或必要?我想到的唯一一个应用程序是在chrooted环境中提供一个系统文件的副本,而在这种应用程序中,符号链接无法完成这项工作。

在移动原始文件时,硬链接非常有用。例如,将文件从/bin移动到/usr/bin或移动到/usr/local/bin。任何指向/bin中文件的符号链接都会因此而断开,但是直接指向文件inode的硬链接则无关紧要

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

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

我还认为,像mmap(2)甚至open(2)这样的东西使用与硬链接相同的功能来保持文件的inode处于活动状态,这样即使文件被取消链接(2),inode仍然允许进程继续访问,并且只有进程关闭后,文件才会真正消失。这就允许更安全的临时文件(如果您可以以原子方式打开和取消链接,可能有一个POSIX API,我不记得了,那么您确实有一个安全的临时文件),在那里您可以读/写数据,而不需要任何人能够访问它。在/proc使每个人都能够查看文件描述符之前,这是真的,但那是另一回事了


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

硬链接在执行增量备份时非常有用。例如,见。我们的想法是使用硬链接进行复制:

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

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

一些示例可能会有所帮助

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

$ printf Cat > foo
$ printf Dog > bar
创建硬链接和软链接(也称为符号链接):

通过增加大小以长格式列出目录内容:

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
这告诉我们

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

    • 软链接:
      lrwxr-xr-x
      • 文件类型:
        l
        =符号链接
      • 所有者权限:
        rwx
        =可读、可写、可执行
      • 组权限:
        r-x
        =可读、不可写、可执行
      • 其他权限:
        r-x
        =可读、不可写、可执行
    • 硬链接:
      -rw-r--r--
      • 文件类型:
        -
        =常规文件
      • 所有者权限:
        rw-
        =可读、可写、不可执行
      • 组权限:
        r--
        =可读、不可写、不可执行
      • 其他权限:
        r--
        =可读、不可写、不可执行
  • 第二列:硬链接文件的链接数较高

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

  • 最后一栏:t
    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
    
    $ mv foo foo-new
    $ cat foo-hard
    Cat
    
    $ printf Dog >> foo
    $ cat foo-hard
    CatDog
    
    $ mv bar bar-new
    $ ls bar-soft
    bar-soft
    $ cat bar-soft  
    cat: bar-soft: No such file or directory
    
    $ find -L . -samefile f6 
    
    > ./f1
    > ./f6
    > ./f7
    > ./t2/f2
    > ./t2/f8
    
    $ find . -xdev -samefile f6
    
    > ./f6
    > ./f7
    > ./t2/f8
    
    /home/bobbin/sync.sh
    /root/synchro
    
    echo "111" > a
    ln a b
    ln -s a c
    
    cat a --> 111
    cat b --> 111
    cat c --> 111
    
    rm a
    cat a --> No such file or directory
    cat b --> 111
    cat c --> No such file or directory
    
    $ echo 'Hello, World!' > myfile.txt
    
    $ ln myfile.txt my-hard-link
    
    $ ln -s myfile.txt my-soft-link
    
    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"
    
    mklink /H Link_name target_path
    
    mklink /J link_name target_path
    
    struct dentry{
        ino_t ino;
        char  name[256];
    }
    
    struct inode{
          link_t nlink; 
          ...
    }
    
    struct dentry{
         ino_t ino; /* such as 15 */
         char  name[256]; /* "1" */
    } 
    
       struct inode{ /* inode number 15 */
             link_t nlink; /* nlink = 1 */
             ...
        }
    
      struct dentry{
         ino_t ino; /* 15 */
         char  name[256]; /* 100 */
      }
    
       struct inode{ /* inode numebr 15 */
             link_t nlink; /* nlink = 2 */
             ...
        }
    
      struct dentry{
            ino_t ino; /* such as 16 */
            char  name[256]; /* "200" */
      }
    
       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 */
    
    ln -s /long/folder/name/on/long/path/file.txt /short/file.txt
    
    $ ls -lh /myapp/dev/
    total 10G
    -rw-r--r-- 2 root root 10G May 22 12:09 application.bin