SYMLINK - Linux手册页
Linux程序员手册 第7部分
更新日期: 2020-06-09
名称
symlink-符号链接处理
说明
符号链接是充当指向其他文件的指针的文件。要了解它们的行为,您必须首先了解硬链接的工作方式。
硬链接到文件与原始文件没有区别,因为它是对原始文件名基础对象的引用。 (准确地说:到文件的每个硬链接都是对同一inode编号的引用,其中inode编号是inode表的索引,该索引包含有关文件系统上所有文件的元数据。请参见stat(2)。 )对文件的更改与引用该文件的名称无关。硬链接可能不会引用目录(以防止在文件系统树中出现循环的可能性,这可能会使许多程序迷惑),并且可能不会引用不同文件系统上的文件(因为inode编号在文件系统中并不唯一)。
符号链接是一种特殊类型的文件,其内容是一个字符串,该字符串是另一个文件(链接所指向的文件)的路径名。 (可以使用readlink(2)读取符号链接的内容。)换句话说,符号链接是指向另一个名称的指针,而不是指向基础对象的指针。因此,符号链接可能引用目录,并且可能会跨越文件系统边界。
不需要符号链接引用的路径名存在。指向不存在的路径名的符号链接被称为悬挂链接。
由于符号链接及其引用的对象共存于文件系统名称空间中,因此在区分链接本身与引用的对象时会产生混淆。在历史系统上,命令和系统调用以某种特定的方式采用了自己的链接跟踪约定。本文概述了在Linux和其他系统上实现的更统一方法的规则。站点本地应用程序也必须遵守这些规则,因此用户界面应尽可能保持一致,这一点很重要。
Magic links
有一类特殊的类似于符号链接的对象,称为"魔术链接",可以在某些伪文件系统中找到,例如proc(5)(示例包括/ proc / [pid] / exe和/ proc / [pid] / fd / *)。与普通的符号链接不同,魔术链接不是通过路径名扩展来解析的,而是充当对内核自身文件句柄表示形式的直接引用。这样,这些魔术链接使用户可以访问无法用常规路径引用的文件(例如,仍由运行程序引用的未链接文件)。
因为它们可以绕过基于常规mount_namespaces(7)的限制,所以魔术链接已被用作各种漏洞利用的攻击媒介。
Symbolic link ownership, permissions, and timestamps
可以使用lchown(2)更改现有符号链接的所有者和组。只有在设置了粘性位的目录中删除或重命名链接时,符号链接的所有权才有意义(请参阅stat(2))。
可以使用utimensat(2)或lutimes(3)来更改符号链接的最后访问时间戳和最后修改时间戳。
在Linux上,任何操作均不使用普通符号链接的权限。权限始终为0777(针对所有用户类别的读取,写入和执行),并且无法更改。
但是,魔术链接不遵循此规则。他们可以具有非0777模式,尽管当前在任何权限检查中均未使用此模式。
Obtaining a file descriptor that refers to a symbolic link
使用O_PATH和O_NOFOLLOW标志的组合来打开(2)会产生一个文件描述符,该文件描述符可以作为dirfd参数传递给系统调用,例如fstatat(2),fchownat(2),fchmodat(2),linkat(2)和readlinkat(2),以便对符号链接本身(而不是它所引用的文件)进行操作。
默认情况下(即,如果未指定AT_SYMLINK_FOLLOW标志),如果将name_to_handle_at(2)应用于符号链接,它将产生符号链接的句柄(而不是其引用的文件)。然后,可以通过在对open_by_handle_at(2)的后续调用中指定O_PATH标志,来获得符号链接的文件描述符(而不是符号引用的文件)。同样,该文件描述符可用于上述系统调用中以对符号链接本身进行操作。
Handling of symbolic links by system calls and commands
通过对链接本身进行操作或对链接所引用的对象进行操作,可以处理符号链接。在后一种情况下,应用程序或系统调用被称为跟随该链接。符号链接可以引用其他符号链接,在这种情况下,将取消引用该链接,直到找到不是符号链接的对象,找到引用不存在的文件的符号链接或检测到循环为止。 (通过对可遵循的链接数设置上限来完成循环检测,如果超过此限制,则会导致错误。)
有三个单独的领域需要讨论。它们如下:
- 1.
- 符号链接用作系统调用的文件名参数。
- 2.
- 指定为不遍历文件树的实用程序的命令行参数的符号链接。
- 3.
- 遍历文件树的实用程序遇到的符号链接(在命令行上指定,或者在文件层次结构遍历中遇到)。
在描述系统调用和命令对符号链接的处理之前,我们需要一些术语。给定路径名形式为a / b / c,最后斜杠(即a / b)之前的部分称为dirname组件,最后斜杠(即c)之后的部分称为basename组件。
Treatment of symbolic links in system calls
第一个区域是符号链接,用作系统调用的文件名参数。
传递给系统调用的路径名中的符号链接的处理如下:
- 1.
- 在路径名的目录名组件中,几乎每个系统调用中都始终跟随符号链接。 (命令也是如此。)一个例外是openat2(2),它提供了一些标志,这些标志可用于显式防止目录名组件中符号链接的跟随。
- 2.
- 除非另有说明,否则所有系统调用都遵循路径名的basename组件中的符号链接。例如,如果有一个符号链接slink指向名为afile的文件,则系统调用open(slink ...)将返回引用该文件afile的文件描述符。
各种系统调用都不遵循路径名的basename组件中的链接,而是在符号链接本身上进行操作。它们是:lchown(2),lgetxattr(2),llistxattr(2),lremovexattr(2),lsetxattr(2),lstat(2),readlink(2),rename(2),rmdir(2)和取消链接(2)。
某些其他系统调用可以选择跟随路径名的basename组件中的符号链接。它们是:faccessat(2),fchownat(2),fstatat(2),linkat(2),name_to_handle_at(2),open(2),openat(2),open_by_handle_at(2)和utimensat(2);有关详细信息,请参见其手册页。因为remove(3)是unlink(2)的别名,所以该库函数也不遵循符号链接。将rmdir(2)应用于符号链接时,它将失败,并显示错误ENOTDIR。
link(2)需要特别讨论。 POSIX.1-2001指定link(2)如果它是符号链接,则应取消引用oldpath。但是,Linux不会这样做。 (默认情况下,Solaris是相同的,但是可以使用适当的编译器选项来获得POSIX.1-2001指定的行为。)POSIX.1-2008更改了规范,以允许实现中的任何一种行为。
Commands not traversing a file tree
第二个区域是符号链接,指定为不遍历文件树的命令的命令行文件名参数。
除非另有说明,否则命令将遵循称为命令行参数的符号链接。例如,如果有一个符号链接slink指向一个名为afile的文件,则命令cat slink将显示文件afile的内容。
重要的是要意识到,该规则包括可以选择遍历文件树的命令。例如,命令chown文件包含在此规则中,而执行树遍历的命令chown -R文件则没有。 (后者在下面的第三部分中介绍。)
例如,如果明确希望该命令在符号链接上操作而不是在符号链接上进行操作,则-例如,希望chown slink更改slink所在文件的所有权,无论它是否是符号链接- -然后应使用-h选项。在上面的示例中,chown root slink会更改slink引用的文件的所有权,而chown -h root slink会更改slink本身的所有权。
此规则有一些例外:
- *
- mv(1)和rm(1)命令不遵循命名为参数的符号链接,而是分别尝试重命名和删除它们。 (请注意,如果符号链接通过相对路径引用文件,则将其移动到另一个目录可能会导致它停止工作,因为该路径可能不再正确。)
- *
- ls(1)命令也是该规则的例外。为了与历史系统兼容(当ls(1)未进行树遍历时-即未指定-R选项),如果-H或-L,则ls(1)命令将遵循命名为参数的符号链接指定了option,或者未指定-F,-d或-l选项。 (ls(1)命令是唯一的-H和-L选项影响其行为的命令,即使它没有遍历文件树。)
- *
- file(1)命令也是该规则的例外。默认情况下,file(1)命令不跟随命名为参数的符号链接。如果指定了-L选项,file(1)命令的确会跟随命名为参数的符号链接。
Commands traversing a file tree
以下命令可选地或始终遍历文件树:chgrp(1),chmod(1),chown(1),cp(1),du(1),find(1),ls(1),pax(1) ,rm(1)和tar(1)。
重要的是要意识到,以下规则同样适用于遍历文件树时遇到的符号链接和列为命令行参数的符号链接。
第一条规则适用于引用目录以外的文件的符号链接。应用于符号链接的操作是在链接本身上执行的,否则将忽略链接。
rm -r slink directory命令将删除slink以及目录树遍历中遇到的任何符号链接,因为可能会删除符号链接。 rm(1)在任何情况下都不会影响slink引用的文件。
第二条规则适用于引用目录的符号链接。默认情况下,绝对不会引用引用目录的符号链接。这通常被称为"物理"遍历,而不是"逻辑"遍历(其中遵循引用目录的符号链接)。
遵循某些约定,并应尽可能一致地遵循执行文件树遍历的命令:
- *
- 通过指定-H(用于"半逻辑")标志,可以使命令跟随命令行上命名的任何符号链接,无论它们引用的文件类型如何。此标志旨在使命令行名称空间看起来像逻辑名称空间。 (注意,对于并非总是进行文件树遍历的命令,如果未同时指定-R标志,则-H标志将被忽略。)
- 例如,命令chown -HR用户slink将遍历以slink指向的文件中为根的文件层次结构。注意,-H与前面讨论的-h标志不同。 -H标志使命令行上指定的符号链接被取消引用,以同时执行操作和进行树遍历,就像用户已经指定了符号链接指向的文件名一样。
- *
- 通过指定-L(用于"逻辑")标志,可以使命令跟随命令行上命名的任何符号链接,以及遍历过程中遇到的任何符号链接,无论它们引用的文件类型如何。该标志旨在使整个名称空间看起来像逻辑名称空间。 (请注意,对于并非总是进行文件树遍历的命令,如果未同时指定-R标志,则-L标志将被忽略。)
- 例如,命令chown -LR用户slink将更改slink引用的文件的所有者。如果slink指向目录,那么chown将遍历其所引用目录中的文件层次结构。另外,如果在遍历遍历的任何文件树中遇到任何符号链接,它们将以与slink相同的方式处理。
- *
- 可以通过指定-P(用于"物理")标志来提供默认行为。该标志旨在使整个名称空间看起来像物理名称空间。
对于默认情况下不进行文件树遍历的命令,如果未同时指定-R标志,则将忽略-H,-L和-P标志。另外,您可以多次指定-H,-L和-P选项。指定的最后一个确定命令的行为。这样做是为了允许您别名命令以一种方式或另一种方式使用别名,然后在命令行上覆盖该行为。
另外参见
chgrp(1),chmod(1),find(1),ln(1),ls(1),mv(1),namei(1),rm(1),lchown(2),链接(2), lstat(2),readlink(2),rename(2),symlink(2),unlink(2),utimensat(2),lutimes(3),path_resolution(7)
出版信息
这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/。