Linux 符号链接的背后是什么?

Linux 符号链接的背后是什么?,linux,unix,linux-kernel,symlink,inode,Linux,Unix,Linux Kernel,Symlink,Inode,UNIX/Linux系统如何在内部管理符号链接。众所周知,即使没有实际的目标文件(悬挂链接),符号链接也可能存在。那么,在内部代表符号链接的是什么呢 在Windows中,答案是一个重新分析点 问题: 答案是UNIX/Linux中的inode 如果是,那么目标和链接的inode编号是否相同 如果是,链接inode是否可以拥有与目标inode不同的权限(如果存在)?这不是关于UNIX/Linux,而是关于文件系统实现-但是是的,UNIX/Linux在内核级别使用inode,文件系统实现有inode(

UNIX/Linux系统如何在内部管理符号链接。众所周知,即使没有实际的目标文件(悬挂链接),符号链接也可能存在。那么,在内部代表符号链接的是什么呢

在Windows中,答案是一个
重新分析点

问题:

答案是UNIX/Linux中的
inode

如果是,那么目标和链接的inode编号是否相同


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

这不是关于UNIX/Linux,而是关于文件系统实现-但是是的,UNIX/Linux在内核级别使用inode,文件系统实现有inode(至少是虚拟的)

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

  • “inode”中的标志
    文件类型
    ,告诉系统该文件是“符号链接”
  • 文件内容:目标路径-换句话说:符号链接只是一个文件,其中包含一个在inode中带有标志的文件名
虚拟文件系统也可以有符号链接,因此,请检查FUSE或其他一些文件系统实现源。(ext2/ext3/ufs..等)

所以

答案是UNIX/Linux中的inode吗

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

如果是,那么目标和链接的inode编号是否相同

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

如果是,链接inode是否可以拥有与目标节点不同的权限 inode(如果存在)

这是关于如何处理符号链接文件的。通常,内核不允许更改符号链接权限,并且符号链接始终具有默认权限。您可以编写自己的文件系统,允许对符号链接使用不同的权限,但您会遇到麻烦,因为像
chmod
这样的常见程序本身不会更改符号链接的权限,因此创建这样的文件系统毫无意义)

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

目录是告诉内核“将此文件作为
文件名
inode\u编号
的映射来处理”的文件(以inode中的标志区分)。硬链接只是映射到同一
inode
的文件名。因此,如果目录文件包含:

file_a: 1000
file_b: 1001
file_c: 1000
在该目录中,上述表示为3个文件:

  • inode 1000描述的文件
  • inode 1001和
  • inode 1000再次描述了文件_c(因此它是与文件_a的硬链接,而不是与文件_a的硬链接-因为无法区分哪个文件名先出现-它们是相同的)

这是符号链接的主要区别,在符号链接中,
文件b
(inode 1001)的inode可以有内容“文件a”和一个表示“这是符号链接”的标志。在这种情况下,
file\u b
将是一个符号链接,指向
file\u a

您也可以自己轻松地探索:

$ 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编号,而硬链接具有相同的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)
系统调用来查找有关符号链接本身的信息(其索引节点号等),而
stat(2)
显示有关符号链接目标(如果存在)的信息。Python中的示例:

>>> import os
>>> os.stat("b").st_ino
95905
>>> os.lstat("b").st_ino
96990
readlink()
允许您查找作为给定符号链接中的路径名存储的内容-但是当一个符号链接中的路径名所遍历的元素之一本身就是符号链接时,生活会变得非常有趣。内核可以从容地处理它;人们不一定如此。还有一个
realpath()
,用于确定给定文件的无符号链接绝对路径。