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

我使用的是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 

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

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

它们允许您创建循环

指向目录的硬链接可以链接到自身的父级,从而创建文件系统循环。 例如,这些命令可以创建一个带有后向链接l的循环:

 mkdir -p /tmp/a/b cd /tmp/a/b ln -d /tmp/al 

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

 cd /tmp/a/b/l/b/l/b/l/b/l/b 

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

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

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

使用文件系统循环,存在多个父目录:

 cd /tmp/a/b cd /tmp/a/b/l/b 

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

他们繁殖文件

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

 /tmp/a/b/foo.txt /tmp/a/b/l/b/foo.txt 

是不同的文件。
该文件还有无限多的其他路径。 它们的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 

如何软链接到目录呢?

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

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

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

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

 $ readlink -f /some/symlinked/path 

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

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


来自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 [ ... ] 

“你通常不应该使用硬链接”过于宽泛。 您需要了解硬链接和符号链接之间的区别,并根据需要使用每个链接。 每个都有自己的优点和缺点:

符号链接可以:

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

硬链接可以:

  • 保持他们引用的文件被删除

硬链接在执行“写入时复制”应用程序时特别有用。 它们允许您保留目录结构的备份副本,而仅为两个版本之间更改的文件使用空间。

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

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

 mount -t bind /var/www /home/user/workspace/www 

这非常危险,因为大多数工具和程序都不会意识到绑定 。 我曾经做过类似于上面例子的事情,然后继续前进到rm -rf /home/user 。 幸运的是, /var/www没有任何相关内容。

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