请尝试运行以下脚本:
#!/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,但它太小了,除了命令解释器真正提供的绝对基本功能之外,它还依赖于许多操作系统工具。在这方面,它是一个非常好的教学工具。