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


15

我创建了具有目录绝对路径的符号链接(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文件吗?


相同的问题交叉发布在SuperUser
Peter.O 2012年

Answers:


13

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

但是,当您运行时ls ../fools并没有意识到shell是通过以下符号链接到达目录的。 lsstat()在“ ../foo”上执行。“ ..”部分来自当前目录,该目录的父目录只有一个“ ..”条目。整个符号链接不会改变目录中包含单个“。”的方式。和一个“ ..”条目。通过符号链接,内核可以在文件路径中插入额外的间接层。当您将“ ../whatever”传递给open()或时stat(),内核仅使用进程的当前工作目录进行调用,以找出哪个目录以“ ..”命名。


17

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

谢谢,我知道set -P功能,但是被ls命令的行为所迷惑……
user478681

就像我说的那样,use set -P和ls行为开始变得有意义。:)
2012年

2

布鲁斯和艾姆斯给出了漂亮的答案,解释了背后的行为。但是要真正做到ls ../foo您所要求的,您可以使用类似

ls $(dirname $PWD)/foo

1

你不能这样做,因为/tmp/A/Blink 实际/tmp/B。因此,ls ../A/foo确实有效。

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

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

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


1
cd -P似乎更简单。
jw013

@ jw013:你是对的;它是。我不知道..谢谢..
Peter.O 2012
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.