符号链接背后是什么?

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

在Windows中,答案是reparse point

问题:

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

如果是,那么inode号码是否与目标和链接相同?

如果是的话,链接索引节点可以具有不同于目标索引节点(如果存在)的权限?

Solutions Collecting From Web of "符号链接背后是什么?"

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

在一般情况下,符号链接是简单的文件(顺便说一句,目录也是文件),具有:

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

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

所以,

在UNIX / Linux中,答案是一个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
  • file_c再次由inode 1000描述(所以它是file_a 硬链接,而不是硬链接 file_a – 因为不可能先告诉哪个文件名 – 它们是相同的)。

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

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

 $ touch a $ ln -sab $ ln ac $ 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编号。 你可以看到符号链接有一个不同的索引节点号,而硬链接有相同的。 您也可以使用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)系统调用来查找有关符号链接本身(其inode编号等)的信息,而stat(2)显示有关符号链接目标的信息(如果存在) 。 Python中的示例:

 >>> import os >>> os.stat("b").st_ino 95905 >>> os.lstat("b").st_ino 96990