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


129

我正在使用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中是否相同?



2
尝试ln -F <src> <dst>,它可能会起作用。当然,它曾经在旧版本的Unix中为超级用户工作。有谁记得这是UCB还是System V?是的,坏事可能发生,但通常不会发生。我记得,我rmdir不知道要进行过去的硬链接删除。但是,用户可能会感到困惑并删除错误的内容。
史蒂夫·投手

@StevePitchers如何rmdir以特殊方式处理硬链接?硬链接只是普通链接-只是一个附加链接。要查找是否存在没有额外录制内容的异常额外链接甚至不容易。
Volker Siegel

1
每个节点存储指向它的硬链接数:仅在没有剩余链接时才释放内容。因此rmdir可以判断目录是否有来自其他地方的链接。递归删除rm -r必须仔细编码,以确保即使出现诸如“权限被拒绝”之类的错误,它也能正确执行。BTW,UCB = BSD,=!
Steve Pitchers 2015年

2
我已经ln -F在目录上完成了工作。但是您以后不敢删除目录,以免损坏文件系统。
Edward Falk

Answers:


159

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

它们允许您创建循环

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

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

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

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
因此,它有两个父目录。

他们乘文件

解决符号链接后,通过路径标识文件。所以

/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

那么如何软链接到目录?

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

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

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

该命令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
        [  ...  ]

1
为什么软链接不能全部完成?
塔奈2015年

1
@Tanay对,它可以帮助扩展将其与具有软链接的类似案例进行比较。我会尽力。
Volker Siegel

究竟这仅与目录有关吗?以我的理解,这些问题也是硬链接文件的问题。而且,我认为硬链接是更改给定目录权限以允许其他人进入内部的一种简便方法,而不必也允许其他人进入父链。如果您没有添加/修改组的能力​​,这听起来非常有用...
inetknght

很好的答案,但是……苹果公司是如何为Time Machine解决这些问题的?
Damien

听起来很有趣!但是我对这个问题一无所知-您能给我一个提示吗?
Volker Siegel '18

77

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

符号链接可以:

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

硬链接可以:

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

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

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


41
关于最后一段,如果您编辑“复制的”硬链接文件,则原始文件也会更改-请参见unix.stackexchange.com/questions/70531/…– marcin 2014
6

32
这种对硬链接的描述颇具误导性。硬链接“保留其所引用的文件不会被删除”是绝对正确的,但这只是硬链接的副作用。您可以在一个目录中创建硬链接,更改“原始”文件,然后期望这些硬链接以某种方式指向旧内容,这当然不是正确的。实际上,硬链接的指导性事实是,它根本不是链接,至少与原始“文件”无关,后者仅仅是指向文件的名称。硬链接只是指向同一文件的另一个名称。
马蒂2015年

7
备份的想法很好,实际上我经常使用它,但是我认为应该警告用户更改文件也会更改备份。
2015年

3
哎呀,符号链接根本不需要指向任何东西。ln -s "Don't use this directory" README是合法的。实际上,如果您考虑一下,目录可以用作关系数据库,而根本不包含任何实际文件。
爱德华·福尔克

5
-1这不能回答问题,有些信息是完全错误的。
wjandrea

43

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

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

这是非常危险的,因为大多数工具和程序都不会意识到绑定。我曾经在上述示例中执行过类似的操作,然后继续执行rm -rf /home/user。幸运的是,中没有任何相关内容/var/www


6
我已经习惯了mount --bind <src> <dest>。小心使用,不要擦拭src;)
kachar 2014年

1
我得到:mount: unknown filesystem type 'bind'
Wizek '16

4
在Busybox上,它mount -o bind src dest
Mat M

@MatM与Debian相同
hanshenrik

2
如果只需要挂载以进行读取,则可以在挂载点上设置权限,从而避免出现此rm -rf问题。superuser.com/questions/320415/...
zanerock

19

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


17
硬链接有很好的用例。说您通常不应该使用它们有点宽泛。
桑德·斯特凡

4
+2用于提供实际上可以回答OP的问题(和我的问题)的链接,+ -1用于提供意见(“您通常不应该使用硬链接” –如果它有链接来支持它,那没关系)。很好,因为我还是不能给+2。; D
msb 2014年

3
链接“它们破坏了文件系统结构”不起作用。
查理·帕克

5
尝试总结答案中链接的内容,并保留该链接作为参考。谢谢您,这是Stack Exchange避免链接腐烂的良好做法。
Oxwivi 2014年

3
做得好@CharlieParker; 有史以来最好的无意(?)具有讽刺意味的评论:)
Eliran Malka
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.