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

use*_*681 15 shell bash directory cd-command symlink

我已经创建了带有目录(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
Run Code Online (Sandbox Code Playgroud)

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

$ cd /tmp/A
$ pwd
/tmp/A
$ cd Blink
$ pwd
/tmp/A/Blink
Run Code Online (Sandbox Code Playgroud)

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

ls: ../foo: No such file or directory
Run Code Online (Sandbox Code Playgroud)

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

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

ams*_*ams 17

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

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

$ pwd
/tmp/A/Blink
$ pwd -L
/tmp/A/Blink
$ pwd -P
/tmp/B
Run Code Online (Sandbox Code Playgroud)

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

$ cd /tmp/A/Blink
$ pwd
/tmp/A/Blink
$ cd -P ..
$ pwd -P
/tmp
Run Code Online (Sandbox Code Playgroud)

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

$ set -P
$ cd /tmp/A/Blink
$ pwd
/tmp/B
Run Code Online (Sandbox Code Playgroud)


Bru*_*ger 13

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

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