为什么硬链接似乎占据与原始链接相同的空间?


14

多亏了在这里和此页面的一些常见问题解答,我现在了解了链接。我看到硬链接用不同的名称引用相同的inode,而副本是不同的“节点,具有不同的名称。加上软链接具有与它们的inode相同的原始文件名和路径,因此如果移动文件,则链接会中断。

因此,我用一些文件(下面的“ saluton_mondo.cpp”)测试了我学到的东西,制作了一个硬链接和一个软链接以及一个副本。

jmcf125@VMUbuntu:~$ ls -lh soft hard copy s*.cpp
-rw-rw-r-- 1 jmcf125 jmcf125 205 Aŭg 27 16:10 copy
-rw-rw-r-- 2 jmcf125 jmcf125 205 Aŭg 25 13:34 hard
-rw-rw-r-- 2 jmcf125 jmcf125 205 Aŭg 25 13:34 saluton_mondo.cpp
lrwxrwxrwx 1 jmcf125 jmcf125  17 Aŭg 27 16:09 soft -> saluton_mondo.cpp

我发现尴尬的是,硬链接的大小与原始大小相同,并且在逻辑上与副本大小相同。如果硬链接和原始链接共享同一个索引节点(即具有数据且仅在文件名上有所不同),那么硬链接不应该仅使用其名称的空间而不是205个字节吗?还是ls -lh返回的原始文件的大小?但是,我怎么知道文件名占用什么空间呢?这里说硬链接没有大小。他们的文件名和原始文件名一起保存吗?硬链接的文件名存储在哪里?

Answers:


16

文件是具有元数据的索引节点,其中包含指向何处查找数据的指针列表。

为了能够访问文件,您必须将其链接到目录(将目录视为电话目录,而不是文件夹),即在一个或多个目录中添加一个或多个条目以将名称与该文件相关联。

所有这些链接,这些文件名都指向同一文件。没有一个是原始的,另一个是链接。它们都是目录树中相同文件(相同inode)的访问点。当您获得文件的大小(lstat系统调用)时,您正在检索存储在索引节点中的信息(上面提到的元数据),无论哪个文件名,使用哪个链接引用该文件都无关紧要。

相反,符号链接是另一个文件(另一个inode),其内容是目标文件的路径。像任何其他文件一样,这些符号链接必须链接到目录(必须具有名称),以便您可以访问它们。您也可以有多个指向符号链接的链接,换句话说,可以为符号链接指定多个名称(在一个或多个目录中)。

$ touch a
$ ln a b
$ ln -s a c
$ ln c d
$ ls -li [a-d]
10486707 -rw-r--r-- 2 stephane stephane 0 Aug 27 17:05 a
10486707 -rw-r--r-- 2 stephane stephane 0 Aug 27 17:05 b
10502404 lrwxrwxrwx 2 stephane stephane 1 Aug 27 17:05 c -> a
10502404 lrwxrwxrwx 2 stephane stephane 1 Aug 27 17:05 d -> a

文件号10486707上方是常规文件。当前目录中的两个条目(一个名为name a,一个名为name b)链接到该目录。由于链接计数为2,我们知道在当前目录或任何其他目录中没有该文件的其他名称。文件号10502404是另一个文件,这一次是symlink类型,两次链接到当前目录。它的内容(目标)是相对路径“ a”。

请注意,如果10502404链接到了当前目录以外的其他目录,则根据其访问方式,它通常会指向不同的文件。

$ mkdir 1 2
$ echo foo > 1/a
$ echo bar > 2/a
$ ln -s a 1/b
$ ln 1/b 2/b
$ ls -lia 1 2
1:
total 92
10608644 drwxr-xr-x   2 stephane stephane  4096 Aug 27 17:26 ./
10485761 drwxrwxr-x 443 stephane stephane 81920 Aug 27 17:26 ../
10504186 -rw-r--r--   1 stephane stephane     4 Aug 27 17:24 a
10539259 lrwxrwxrwx   2 stephane stephane     1 Aug 27 17:26 b -> a

2:
total 92
10608674 drwxr-xr-x   2 stephane stephane  4096 Aug 27 17:26 ./
10485761 drwxrwxr-x 443 stephane stephane 81920 Aug 27 17:26 ../
10539044 -rw-r--r--   1 stephane stephane     4 Aug 27 17:24 a
10539259 lrwxrwxrwx   2 stephane stephane     1 Aug 27 17:26 b -> a
$ cat 1/b
foo
$ cat 2/b
bar

除了链接文件的目录外,文件没有与它们关联的名称。它们的名称所占用的空间是这些目录中的条目,占目录的文件大小/磁盘使用量的原因。

您会注意到删除文件的系统调用是unlink。也就是说,您不删除文件,而是将它们从引用它们的目录中取消链接。一旦从具有给定文件条目的最后一个目录中取消链接,则该文件将被销毁(只要没有进程即可)打开)。


啊...现在我明白了。因此,名为“ hi”的文件及其精确副本为“ajhĝjdmjefsjmksgskgjkmŝŭna”占用的空间完全相同;因为它们的名称不计入lstat获得其大小的那个系统调用。
JMCF125

@ JMCF125,是的,它们的名称所占大小是相应目录中的条目,占目录文件的大小。
斯特凡Chazelas

谢谢。您可以在回答中包括吗?等等,我先澄清我的问题。
JMCF125

5

硬链接本质上是原始文件。因此,您看到的报告大小就是链接到的文件的大小。这是链接,只需要他们的名字(有点)的空间。

就文件系统而言,硬链接和原始文件是相同的,它们指向相同的inode,因此报告的大小相同。


但是硬链接的名称必须有空格,对吗?
JMCF125

参见下面的@stephan的答案,他对此做了更好的解释。
terdon

2
@ JMCF125是的,但是该空间位于目录内。如果创建足够的文件,您会注意到目录大小会增加。文件的大小不包括其元数据(例如名称)。
吉尔(Gilles)'所以

@Gilles,谢谢,但是@Stephane已经用该信息更新了他的答案。另外,现在我想起来更好,/必须将名称存储在自身中,就像您cd ../中保存时一样/
JMCF125
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.