为什么 Linux 中符号链接目录中的“..”引用了“不正确”的目录?

为什么 Linux 中符号链接目录中的“..”引用了“不正确”的目录?

请尝试运行以下脚本:

#!/bin/bash
mkdir a
mkdir a/asub
mkdir b
ln -sfr a/asub b/bsub
touch a/this_file_is_in_a
touch b/this_file_is_in_b
cd b/bsub
echo "I'm in directory: $(pwd)"
echo This is the contents of the upper directory:
ls ..

你希望得到什么?可能是目录的内容b。然而,事实并非如此。我已经在目录中运行了它/tmp/bb

下面是结果:

wzab@WZabHP:/tmp/bb$ ./ls_tester.sh
I'm in directory: /tmp/bb/b/bsub
This is the contents of the upper directory:
asub  this_file_is_in_a

因此,尽管pwd返回的正确路径是b子目录,但“..”指的是子目录a。是我对符号链接的理解不正确,还是Linux中的一个错误?

答案1

考虑到目录作为小文件,本质上是列表或表格。

目录“知道”其父目录的原因是因为在幕后使用了完整的目录。为了方便起见,每个目录中都存在指向上级目录和当前目录的链接。

目录的符号链接就像文件的链接。一旦进入该链接目录“内部”,您就位于该链接目录中,并且 和...指向父目录和当前(真实)目录的硬链接,即您“通过”该符号链接(或者更确切地说是哪个符号链接)“获得”的信息技术上已经丢失了。

创建新目录时,总是会创建这三个硬链接,至少在 unixoidal 系统上(但有一些较旧的 Unices 允许任意硬链接)。

然而、贝壳中含有大量的“方便糖”。 shell 会为你记住这一点实际上你来自一个符号链接,它会为你“重新连接”相关目录。

shell 内置函数pwd也知道这一点,并以这种方式工作。应用/usr/bin/pwd程序将简单地声明完全限定的路径,即不通过符号链接的路径。如果没有,将有很多可能的方法来到达该目录,并且从技术上讲,所有这些组合(如果您有循环符号链接,则可以是无限的)都必须被打印。

大多数(虽然可能不是全部,我不确定)shell 的cd命令都有选项-P,当通过符号链接进入目录时,将使用物理目录结构,而不是遵循符号链接。您可以在“bash_builtins”的手册页man cd(很容易通过内部到达bash)。

以下是摘录man zshbuiltins

如果给出了 -P 选项或设置了 CHASE_LINKS 选项,则符号链接将解析为其真实值。如果指定了 -L 选项,则无论 CHASE_LINKS 选项的状态如何,符号链接都会保留在目录中(并且不会解析)。

(bash 的手册页包含类似的部分)

您可能想看看真的最小的外壳,比如s。我并不是建议您应该将它用作日常 shell,但它太小了,除了命令解释器真正提供的绝对基本功能之外,它还依赖于许多操作系统工具。在这方面,它是一个非常好的教学工具。

相关内容