为什么目录不允许硬链接?

Nis*_*hay 168 filesystem directory hard-link

我正在使用 Ubuntu 12.04。当我尝试为任何目录创建硬链接时,它失败了。我可以为文件系统边界内的文件创建硬链接。我知道我们不能为文件系统之外的文件创建硬链接的原因。

我试过这些命令:

$ ln /Some/Direcoty /home/nischay/Hard-Directory
hard link not allowed for directory
$ sudo ln /Some/Direcoty /home/nischay/Hard-Directory
[sudo] password for nischay: 
hard link not allowed for directory
Run Code Online (Sandbox Code Playgroud)

我只想知道这背后的原因。对于所有 GNU/Linux 发行版和 Unix 风格(BSD、Solaris、HP-UX、IBM AIX)还是仅在 Ubuntu 或 Linux 中都相同?

Vol*_*gel 201

目录硬链接以多种方式破坏文件系统

它们允许您创建循环

指向目录的硬链接可以链接到自身的父目录,这会创建文件系统循环。例如,这些命令可以使用反向链接创建一个循环l

mkdir -p /tmp/a/b
cd /tmp/a/b
ln -d /tmp/a l
Run Code Online (Sandbox Code Playgroud)

具有目录循环的文件系统具有无限深度:

cd /tmp/a/b/l/b/l/b/l/b/l/b
Run Code Online (Sandbox Code Playgroud)

在遍历这样的目录结构时避免无限循环有点困难(尽管例如 POSIX 需要find避免这种情况)。

具有这种硬链接的文件系统不再是树,因为根据定义,树不能包含循环。

他们打破了父目录的明确性

对于文件系统循环,存在多个父目录:

cd /tmp/a/b
cd /tmp/a/b/l/b
Run Code Online (Sandbox Code Playgroud)

在第一种情况下,/tmp/a/tmp/a/b.
在第二种情况下,/tmp/a/b/l是 的父目录/tmp/a/b/l/b,与/tmp/a/b.
所以它有两个父目录。

他们乘以文件

解析符号链接后,文件由路径标识。所以

/tmp/a/b/foo.txt
/tmp/a/b/l/b/foo.txt
Run Code Online (Sandbox Code Playgroud)

是不同的文件。
文件有无限多的进一步路径。当然,它们的 inode 数量是相同的。但是,如果您没有明确地期望循环,则没有理由进行检查。

目录硬链接也可以指向子目录,或者既不是任何深度的子目录也不是父目录的目录。在这种情况下,作为链接子文件的文件将被复制到由两个路径标识的两个文件中。

你的榜样

$ ln /Some/Direcoty /home/nischay/Hard-Directory
$ echo foo > /home/nischay/Hard-Directory/foobar.txt
$ diff -s /Some/Direcoty/foobar.txt /home/nischay/Hard-Directory/foobar.txt
$ echo bar >> /Some/Direcoty/foobar.txt
$ diff -s /Some/Direcoty/foobar.txt /home/nischay/Hard-Directory/foobar.txt
$ cat /Some/Direcoty/foobar.txt
foo
bar
Run Code Online (Sandbox Code Playgroud)

那么到目录的软链接如何工作呢?

可能包含软链接甚至软链接目录循环的路径通常仅用于识别和打开文件。它可以用作正常的线性路径。

但是还有其他情况,当路径用于比较文件时。在这种情况下,可以首先解析路径中的符号链接,将其转换为最小的、普遍同意的表示创建规范路径

这是可能的,因为软链接都可以扩展为没有链接的路径。对路径中的所有软链接执行此操作后,剩余路径是树的一部分,其中路径始终是明确的。

该命令readlink可以解析其规范路径的路径:

$ readlink -f /some/symlinked/path
Run Code Online (Sandbox Code Playgroud)

软链接与文件系统使用的不同

软链接不会造成所有问题,因为它与文件系统内的链接不同。它可以与硬链接区分开来,并在需要时解析为没有符号链接的路径。
从某种意义上说,添加符号链接不会改变基本的文件系统结构——它保留了它,但会增加更多的结构,如应用程序层。


来自man readlink

 NAME
        readlink - print resolved symbolic links or canonical
        file names

 SYNOPSIS
        readlink [OPTION]... FILE...

 DESCRIPTION
        Print value of a symbolic link or canonical file name

        -f, --canonicalize
               canonicalize by  following  every  symlink  in
               every component of the given name recursively;
               all but the last component must exist
        [  ...  ]
Run Code Online (Sandbox Code Playgroud)


小智 85

“无论如何,您通常都不应该使用硬链接”过于宽泛。您需要了解硬链接和符号链接之间的区别,并酌情使用它们。每个都有自己的优点和缺点:

符号链接可以:

  • 指向目录
  • 指向不存在的对象
  • 指向同一文件系统外的文件和目录

硬链接可以:

  • 防止他们引用的文件被删除

硬链接在执行“写时复制”应用程序时特别有用。它们允许您保留目录结构的备份副本,同时只为在两个版本之间更改的文件使用空间。请注意,实现必须首先断开链接(否则修改也将应用于原始文件!)。

该命令cp -al在这方面特别有用。它制作了一个目录结构的完整副本,其中所有文件都由指向原始文件的硬链接表示。然后您可以继续更新结构中的文件(在仅创建这些文件的实际副本之后),并且只有您更新的文件才会占用额外的空间。这在维护多代备份时特别有用。

  • 关于最后一段,如果您编辑“复制的”硬链接文件,原始文件也会更改 - 请参阅 http://unix.stackexchange.com/questions/70531/cp-al-snapshot-whose-hard-links-get-编辑时定向到新文件 (48认同)
  • 这种硬链接的描述相当具有误导性。硬链接“防止它们引用的文件被删除”基本上是正确的,但这只是硬链接的副作用。您可以在一个目录中创建硬链接,更改“原始”文件,然后期望硬链接以某种方式指向旧内容,这当然不是真的。事实上,硬链接的指导原则是它根本不是一个链接,至少不是原始“文件”,它只是一个指向文件的名称。**硬链接只是指向同一文件的另一个名称。** (38认同)
  • 备份的想法很好,我实际上经常使用它,但我认为应该警告用户,更改文件也会更改备份。 (7认同)
  • -1 这不能回答问题,有些信息是完全错误的。 (7认同)
  • 哎呀,符号链接根本不需要指向任何东西。`ln -s "Don't use this directory" README` 是合法的。事实上,如果你仔细想想,目录可以用作关系数据库,根本不包含任何实际文件。 (3认同)
  • 硬链接**不**“写入时复制”。 (2认同)

sta*_*unt 54

仅供参考,您可以使用 mount 实现与目录硬链接相同的功能:

mount -t bind /var/www /home/user/workspace/www
Run Code Online (Sandbox Code Playgroud)

这是非常危险的,因为大多数工具和程序都不会意识到绑定。我曾经在上面的例子中做过类似的事情,然后继续rm -rf /home/user. 幸运的是,在/var/www.

  • 我使用了`mount --bind <src> <dest>`。小心使用,不要擦拭 `src` ;) (7认同)
  • 在 Busybox 上,它`mount -o bind src dest` (5认同)
  • 我得到:`mount: unknown filesystem type 'bind'` (4认同)
  • 如果只需要挂载读取,可以在挂载点设置权限,避免`rm -rf`问题。https://superuser.com/questions/320415/linux-mount-device-with-specific-user-rights (3认同)

ast*_*tex 21

不允许硬链接目录的原因有点技术性。本质上,它们破坏了文件系统结构。无论如何,您通常不应使用硬链接。符号链接允许大多数相同的功能而不会引起问题(例如ln -s target link)。

  • 硬链接有很好的用例。说你通常不应该使用它们有点过于宽泛了。 (26认同)
  • 尽量总结回答中链接的内容,保留链接作为参考。这是避免链接腐烂的 Stack Exchange 良好做法,谢谢。 (9认同)
  • +2 用于提供实际回答 OP 问题(和我的)的链接,-1 用于发表意见(“您通常不应该使用硬链接” - 如果它有支持它的链接,那就可以了)。这很好,因为无论如何我都不能给+2。;D (6认同)
  • 链接“他们破坏了文件系统结构”不起作用。 (5认同)
  • 干得好@CharlieParker; 有史以来最好的意外(?)讽刺评论:) (5认同)