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