符号链接背后隐藏着什么?

24

UNIX/Linux系统如何内部管理符号链接。已知符号链接甚至可能没有实际目标文件(悬挂链接)。那么在内部代表符号链接的是什么。

在Windows中,答案是重解析点

问题:

在UNIX/Linux中,答案是inode吗?

如果是,目标和链接的inode号码将相同吗?

如果是,链接inode的权限可以与目标inode(如果存在)不同吗?

2个回答

26

这不是关于UNIX/Linux,而是关于文件系统实现。但是,在内核层面上,Unix/Linux使用inode并且文件系统实现具有inode(至少是虚拟的)。

一般来说,符号链接只是文件(顺便说一句,目录也是文件),它们具有:

  • “inode”中的“file-type”标志,告诉系统此文件是“符号链接”
  • 文件内容:指向目标的路径 - 换句话说:符号链接只是包含有inode标记的文件,其中包含一个文件名。

虚拟文件系统也可以具有符号链接,因此,请检查FUSE或其他文件系统实现源代码(如ext2 / ext3 / ufs..etc)。

所以,

答案是UNIX / Linux中的inode吗?

取决于文件系统的实现,但通常inode包含“文件类型”(以及所有者、访问权限、时间戳、大小、指向数据块的指针)。有些文件系统没有inode(在物理实现中),但仅具有用于与内核保持兼容性的“虚拟inode”。

如果是,则目标和链接的inode编号会相同吗?

不会。通常,符号链接是具有自己inode的文件(具有文件类型、自己的数据块等)。

如果是,则链接inode的权限可以与目标inode(如果存在)的权限不同吗?

这涉及符号链接文件的处理方式。通常,内核不允许更改符号链接的权限 - 符号链接始终具有默认权限。您可以编写自己的文件系统,以允许符号链接具有不同的权限,但是您会遇到麻烦,因为常见的程序例如chmod不会更改符号链接本身的权限,因此制作这样的文件系统没有意义。

要了解硬链接和符号链接之间的区别,您应首先了解目录。

目录是文件(由inode中的标志区分),告诉内核“将此文件处理为从file-name到inode_number的映射”。硬链接只是映射到相同inode的文件名。因此,如果目录文件包含:

file_a: 1000
file_b: 1001
file_c: 1000

以上意味着,在此目录中有3个文件:

  • inode为1000的file_a
  • inode为1001的file_b
  • inode为1000的file_c是一个硬链接, file_a 相连,而不是 指向 file_a - 因为无法确定哪个文件名先出现 - 它们是相同的。

这是与符号链接的主要区别,其中 file_b 的 inode(1001)可以具有“file_a”内容和表示“这是符号链接”的标志。在这种情况下,file_b 将是指向 file_a 的符号链接。


3
你可以自己轻松地探索这个问题:
$ touch a
$ ln -s a b
$ ln a c
$ ls -li
total 0
95905 -rw-r--r-- 1 regnarg regnarg 0 Jun 19 19:01 a
96990 lrwxrwxrwx 1 regnarg regnarg 1 Jun 19 19:01 b -> a
95905 -rw-r--r-- 2 regnarg regnarg 0 Jun 19 19:01 c

ls 命令中的 -i 选项可以显示第一列的 inode 号码,您可以看到符号链接和硬链接所对应的inode号码不同,而硬链接则相同。 您也可以使用 stat(1) 命令:

$ stat a
  File: 'a'
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: 28h/40d Inode: 95905       Links: 2
[...]

$ stat b
  File: 'b' -> 'a'
  Size: 1           Blocks: 0          IO Block: 4096   symbolic link
Device: 28h/40d Inode: 96990       Links: 1
[...]

如果您想以编程方式执行此操作,可以使用lstat(2)系统调用查找有关符号链接本身的信息(例如其i节点编号等),而stat(2)则显示有关符号链接目标(如果存在)的信息。以下是Python示例:
>>> import os
>>> os.stat("b").st_ino
95905
>>> os.lstat("b").st_ino
96990

readlink()函数允许您查找给定符号链接中作为路径名存储的内容,但当路径名中的一个元素本身是符号链接时,情况变得非常有趣。内核可以轻松处理它,但人们不一定能够理解。还有realpath()函数,它确定给定文件的无符号链接的绝对路径。 - Jonathan Leffler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接