创建文件符号链接的目的是什么?

4

最近我在Python中遇到了os库,并发现了符号链接的存在。我想知道符号链接是什么,为什么它存在,以及它的各种用途是什么?


简单来说,如果你熟悉Windows,Linux中的符号链接就像Windows中的快捷方式。 - Kind Stranger
3
在文件之间并不存在所谓的“符号链接”,它只是在名称之间创建的链接。实际上只有一个文件。“在Unix中,名称与文件相对应”: D.M. Ritchie. - user207421
2个回答

12
我将从*nix用户的角度回答(特别是Linux)。如果您想了解这与Windows有何关系,建议您寻找类似于此类的教程。这可能有点绕,但我发现符号链接或symlink最好与硬链接和Linux文件系统的通用属性一起解释。

Linux上的链接和文件

一般来说,在Linux中,所有内容都被视为文件。目录是包含从名称(路径)到inode的映射的文件,后者只是驻留在系统中的不同对象的唯一标识符。基本上,如果我给你一个名称,例如/home/gst/mydog.png,访问过程将首先查看/目录(根目录),在其中找到有关如何找到home的信息,然后打开该文件,查看其中是否存在gst,最后在该文件中尝试查找mydog.png的位置,并在成功后尝试执行其既定任务。回到目录文件,它们包含的映射称为链接。这就带我们来到硬链接和符号链接。

硬链接 vs 符号链接

硬链接只是像我们之前讨论的那样的映射。它直接指向特定对象。另一方面,符号链接并不直接指向一个对象。相反,它只是保存了一个对象的路径。例如,假设我在/home/gst/Desktop/mycat.png处创建了一个到/home/gst/mydog.png的符号链接,并使用os.symlink("/home/gst/mydog.png", "/home/gst/Desktop/mycat.png")。当我尝试打开它时,通常会将名称/home/gst/Desktop/mycat.png解析为/home/gst/mydog.png。通过跟随位于/home/gst/Desktop/mycat.png的符号链接,我实际上(尝试)访问由/home/gst/mydog.png指向的对象。

如果我创建一个硬链接(例如通过调用os.link),我只需将条目添加到相关目录文件中,以便可以按名称跟随到链接的对象。当我创建符号链接时,我创建了一个文件,其中包含指向另一个文件的路径(可能是另一个符号链接)。

更具体地说,如果我将/home/gst/Desktop/mycat.png传递给os.readlink,它将返回/home/gst/mydog.png。当调用os中的函数并将(可选)参数follow_symlinks设置为True时,也会发生这种名称解析,但是,如果它设置为False,则名称不会被解析(例如,当您想要操作符号链接本身而不是它指向的对象时,您会将其设置为false)。来自模块文档

不跟随符号链接:如果follow_symlinksFalse,并且要操作的路径的最后一个元素是符号链接,则该函数将操作符号链接本身,而不是链接指向的文件。(对于POSIX系统,Python将调用该函数的l...版本。)

您可以使用os.supports_follow_symlinks检查您的平台是否支持follow_symlinks。如果不可用,则使用它将引发NotImplementedError

为什么要使用硬链接?

这个问题已经在这里得到了回答,引用自被接受的答案:
硬链接的主要优点是与软链接相比,没有大小或速度惩罚。软链接是在正常文件访问之上的额外间接层;当您打开文件时,内核必须解除链接,这需要一小段时间。链接还占用磁盘上的一小部分空间,以保存链接文本。这些惩罚不存在于硬链接中,因为它们内置于文件系统的结构中。
我想补充说,硬链接允许轻松备份文件的方法。对于每个文件,系统保持其硬链接计数。一旦此计数达到0,文件所在的内存段将被标记为空闲,这意味着系统最终会用另一个数据覆盖它(有效地删除先前的文件-至少在运行进程具有与文件相关联的打开流的情况下不会发生,但这是另一种情况)。那有什么关系呢?
假设您有一个充满文件的巨大目录,您想以某种方式进行操作(重命名一些文件,删除其他文件等),并编写一个脚本来为您完成此操作。但是,您不能完全确定脚本将按预期工作,并且您担心它可能会删除一些错误的文件。您也不想复制所有文件,因为这将占用太多空间和时间。一种解决方案是在文件系统中的某个其他点创建每个文件的硬链接。如果您删除目标目录中的文件,则关联对象仍然可用,因为与之关联的还有另一个硬链接。创建这么多硬链接将消耗比复制所有文件少得多的时间和空间,但它将为您提供合理的备份策略。
符号链接不是这种情况。请记住,符号链接指向其他链接(可能也是另一个符号链接),而不是实际文件。因此,我可以创建到文件的符号链接,但它只会保存链接。如果符号链接指向的(最终)硬链接从系统中删除,尝试解析符号链接将不会引导您到文件。这些符号链接被称为“损坏”或“悬挂”。因此,您不能依赖符号链接来保留对某个文件的访问权限。(相反,删除符号链接不会影响与目标文件关联的链接计数。)那么它们有什么用处呢?
为什么要使用符号链接?
你可以像操作实际文件一样操作符号链接,它们指向某个文件,不过你不能删除。这样,你就可以拥有多个"访问点"来访问文件,而不需要冗余的副本(它们总是访问同一个文件,因此始终保持最新)。如果你想替换正在被访问的文件,你只需要更改一次,所有的符号链接都会指向它(只要保存在其中的路径没有改变)。但是,如果你有一个硬链接指向某个文件,然后用另一个文件替换该文件,你也需要替换硬链接,否则它们仍将指向旧文件。
最后,在同一台 Linux 机器上挂载不同的文件系统并非不常见。也就是说,在文件层次结构的某些地方(比如/home/gst/fs1),数据组织和解释的方式可能与其他地方(比如/home/gst/Desktop/fs2)不同。硬链接只能存在于与其所指向的文件相同的文件系统上。而符号链接可以在一个文件系统上创建,但实际上指向另一个文件系统上的文件(参见这个问题的答案)。

非常出色的解释。感谢你精彩的解说。 - Kiran Hegde

0

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