符号链接的目标是否相对于目标的父目录,如果是,为什么?

jib*_*les 14 symlink

我有以下文件结构:

build/
client/
  –> index.js
Run Code Online (Sandbox Code Playgroud)

当我尝试在构建目录中创建一个名为“client”的符号链接时,它会像这样引用 cwd 中的客户端目录

// Fails
$ pwd
/home/user/
$ ln -s client build/client 
$ stat build/client/index.js
stat: build/client/index.js: stat: Too many levels of symbolic links
Run Code Online (Sandbox Code Playgroud)

我得到上面显示的 ELOOP 错误。当我将目标路径更改为相对于目标路径时,一切都很好:

// Works
$ pwd
/home/user/
$ ln -s ../client build/client 
$ stat build/client/index.js
stat: <outputs file stats>
Run Code Online (Sandbox Code Playgroud)

这是预期的行为吗,请解释原因...

spa*_*cvs 13

对于一个不起作用的,如果我们查看ls -l结果,我们会得到以下结果:

[sparticvs@sparta test]$ ls -l build/
total 0
lrwxrwxrwx. 1 sparticvs sparticvs 6 Dec 17 16:08 client -> client
Run Code Online (Sandbox Code Playgroud)

现在来了解这里发生了什么。让我们看看你调用的命令:

ln -s client build/client
Run Code Online (Sandbox Code Playgroud)

根据手册页,这种格式有两种可能的匹配

SYNOPSIS
       ln [OPTION]... [-T] TARGET LINK_NAME   (1st form)
       ln [OPTION]... TARGET... DIRECTORY     (3rd form)
Run Code Online (Sandbox Code Playgroud)

它将匹配第一个表单(从第一个表单开始)。现在,“目标名称”或client在您的情况下,可以是(根据完整ln手册)任意字符串。他们现在不必解决任何事情,但可以解决将来的事情。您通过调用创建的是“悬空符号链接”,系统不会阻止您创建这些。

现在您的第二次调用ln -s ../client build/client是所谓的“相对符号链接”(如您在自己的帖子中所述)。还有第二种类型,即“绝对符号链接”,可以通过执行ln -s /home/user/client build/client.

不是一个错误。根据手册它指出:

在与当前目录不同的位置创建相对符号链接时,符号链接的分辨率将与当前目录中相同字符串的分辨率不同。因此,许多用户更喜欢首先将目录更改为将创建相关符号链接的位置,以便制表符完成或其他文件解析将找到与符号链接中放置的内容相同的目标。

- 从 info coreutils 'ln invocation'

也就是说,您必须使用目标的相对或绝对路径。


Jos*_* R. 5

这确实是预期的行为。从ln(1)手册页:

符号链接可以包含任意文本;如果稍后解析,则相对链接将相对于其父目录进行解释。

至于它的原因,想象一下如果符号链接是相对于它的源而不是它的目的地来解释的。稍后解决它时,您需要知道创建它时您的 CWD 是什么,这是荒谬的,更不用说不可能了。

此外,通过这种方式,您可以获得一种简洁紧凑的方法来创建骨架目录结构,您可以将其放置在目录树中的任何位置而不会破坏符号链接。

为了给你一个我的意思的例子,假设你正在处理一个项目,并且你已经为它设置了一个完整的目录结构,如下所示:

$ ls -1 /home/you/project
thingummies/
widgets/
wizardry/
Run Code Online (Sandbox Code Playgroud)

现在假设您想创建一个指向widgets/inside的符号链接wizardry/。您有两个选择:

$ ln -s /home/you/project/widgets /home/you/project/wizardry
Run Code Online (Sandbox Code Playgroud)

或者

$ ln -s ../widgets /home/you/project/wizardry
Run Code Online (Sandbox Code Playgroud)

如果您随后尝试移动/home/you/project其他任何位置,则使用第一个表单创建的符号链接将中断,因为它正在寻找/home/you/project/widgets. 第二种形式将保持符号链接的功能,因为它正在寻找../widgets 对于它所在的位置,而不管该位置在目录树中的位置。