目录和相对路径的符号链接

目录和相对路径的符号链接

我创建了带有目录绝对路径的符号链接(Blink),并具有以下示例树:

$ ls -l /tmp/A
total 0
lrwxrwxrwx 1 root root 6 Apr  3 12:27 Blink -> /tmp/B
-rw-r--r-- 1 root root 0 Apr  3 12:27 foo

$ ls -l /tmp/B
total 0
-rw-r--r-- 1 root root 0 Apr  3 12:27 bar

然后我转到 /tmp/A 并将目录更改为 Blink:

$ cd /tmp/A
$ pwd
/tmp/A
$ cd Blink
$ pwd
/tmp/A/Blink

cd ..返回我,/tmp/A 但如果我输入,例如ls ../foo我会收到错误:

ls: ../foo: No such file or directory

内置 cd 命令根据需要解析路径,但外部 ls 将 .. 视为 /tmp/B 的上层,因此无法找到 foo。

这里有什么问题?我可以通过相对路径(如 ../foo)从 /tmp/A/Blink 获取 foo 文件吗?

答案1

shell 将当前工作目录存储在$PWD.这就是 shell 内置命令cd和的用途pwd,并且它将符号链接视为普通目录,如您所见。有时这很有帮助,有时则没有。

您可以使用以下方式找到真实目录pwd(键入help pwd以获取更多详细信息):

$ pwd
/tmp/A/Blink
$ pwd -L
/tmp/A/Blink
$ pwd -P
/tmp/B

同样,cd有一个选项-P(同样,help cd是你的朋友):

$ cd /tmp/A/Blink
$ pwd
/tmp/A/Blink
$ cd -P ..
$ pwd -P
/tmp

最后,您可以完全关闭该“功能”:

$ set -P
$ cd /tmp/A/Blink
$ pwd
/tmp/B

答案2

我认为您无法做到这一点。如今的 Shell 会跟踪它们如何到达当前位置,它们会按名称跟踪当前工作目录,而不是仅仅依靠文件系统和操作系统来保存它。这意味着内置程序可以cd“备份”符号链接,而不仅仅是直接跟踪“..”链。

但是当您运行时ls ../fools并不知道 shell 通过符号链接到达了目录。 将在“../foo”上ls执行操作。 stat()“..”部分来自当前目录,其父目录只有一个“..”条目。整个符号链接并没有改变目录具有单个“.”的方式。和一个“..”条目。符号链接让内核在文件路径中插入额外的间接层。当您将“../whatever”传递给open()或 时stat(),内核仅使用执行调用的进程的当前工作目录来确定哪个目录由“..”命名。

答案3

Bruce 和 ams 给出了漂亮的答案,解释了背后的行为。但要真正做到ls ../foo你所要求的,你可以选择类似的东西

ls $(dirname $PWD)/foo

答案4

你做不到,因为/tmp/A/Blink 实际上/tmp/B。所以,ls ../A/foo确实有效。

相反,您可能会发现能够光盘真实的 /tmp/B目录,而不是别名/tmp/A/Blink.为此,您可以使用以下函数代替cd(您可以将其放入 .bashrc 中)

lcd() { cd $(readlink -f "$1"); }

lcd当然,适用于普通目录和符号链接目录。
注意:readlink -f作用于链接的最终目标(当链接是菊花链时)。

相关内容