为什么在创建之前将当前目录更改为相对符号链接的父目录

Tim*_*Tim 1 symlink ln

来自 coreutils 的手册,对于 ln

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

存储在相对符号链接中的字符串完全由源路径名和目标路径名决定,两者都指定为 的命令行参数ln

我看不到当前目录是如何参与的。所以我不太明白为什么很多用户喜欢在创建之前将当前目录更改为要创建的相对符号链接的父目录。你能改写或举一些例子吗?谢谢。

PSk*_*cik 9

有两件事要记住:

  1. ln -s(没有-r)在您将目标名称传递给它时按字面意思存储目标名称
  2. 如果你传递一个相对目标,它会相对于链接名称解析,而不是你当前的工作目录

例子:

我在/home/user/d0,我想要一个链接,/home/user/file所以我这样做:

ln -s ../file .
Run Code Online (Sandbox Code Playgroud)

../file是来自 的有效路径d0

现在,如果有一个子目录d1( /home/user/d0/d1) 并且我想在那里放置一个指向../file( /home/user/file)的链接而不更改目录,我需要执行以下操作:

ln -s ../../file d1/ 
Run Code Online (Sandbox Code Playgroud)

因为相对路径需要相对于链接名称,而不是我当前的工作目录。../../file(可能)相对于d0(除非有一个名为 的文件/home/file)没有解析,所以我不会自动完成它,这可能会使操作更容易出错。

所以我改成d1第一个:

cd d1
ln -s ../../file . 
Run Code Online (Sandbox Code Playgroud)

现在../../file相对于当前目录和链接名称都有意义;自动完成开始,我得到我的保证我有正确的名字。

GNUln有一个--relative|-r标志,它使您不必手动组合这些相对路径,从而使这变得更容易。有了它,您可以使用相对于当前目录的路径或绝对路径,并且它会相对于链接名称(根据需要)将其相对化。


Ste*_*ris 8

如果你做了

mkdir /tmp/foo
ln -s ../../etc/passwd /tmp/foo
Run Code Online (Sandbox Code Playgroud)

然后访问/tmp/foo/passwd将转换为/tmp/foo/../../etc/passwd- 即/etc/passwd

如果你做了

mkdir /var/tmp/foo
ln -s ../../etc/passwd /var/tmp/foo
Run Code Online (Sandbox Code Playgroud)

然后访问/var/tmp/foo/passwd将转换为/var/tmp/foo/../../etc/passwd- 即/var/etc/passwd

因此,您可以看到“相对符号链接路径”的解析方式不同,具体取决于链接的保存位置。ln根本不涉及您运行命令的当前目录。

为了避免这种混淆,一些用户会在创建符号链接之前更改他们的当前目录

mkdir /tmp/foo
cd /tmp/foo
ln -s ../../etc/passwd
Run Code Online (Sandbox Code Playgroud)

  • `readlink` 只是读取链接,它不会_解析_链接。使用 `realpath` 扩展所有链接和相对路径。 (2认同)