路径分辨率取决于 pwd(符号链接目录)

路径分辨率取决于 pwd(符号链接目录)

这种情况经常发生在/sys/bus树下(bash-5.1):

假设我得到一些foo目录,其中列出了到其他目录的几个符号链接,ls -ails pathto_foo显示了类似的内容:

lrwxrwxrwx 1 root root    0 21 foo1 -> whatever relative path to symlinked foo1
lrwxrwxrwx 1 root root    0 21 foo2 -> whatever relative path to symlinked foo2

这些符号链接目录中的每一个都包含一个名为 的常规文件bar
如果我将当前工作目录更改为pathto_foo/foo1pathto_foo/foo2,我可以file, stat, cat...bar毫无问题。

然而,我的密码被设置为pathto-foo/foo1(或pathto_foo/foo2),sat-ing/c-ating/file-ing ../foo2/bar../foo1/bar分别)将系统地返回:

../foox/bar : No such file or directory

好的!我可以在某种程度上理解和接受这种极其不受欢迎的行为,但是,我只是既不理解也不接受以下不一致之处:

如果,坐在这两个目录中的任何一个目录中,让我们采取pathto_foo/foo1,我想要 stat/cat/file ../foo1/bar(是的!我的意思是 pwd 的相对路径)我会成功的。

那么为什么路径分辨率取决于 pwd 呢? (为什么密码的相对路径的解析方式与其他类似编写的相对路径不同?)
如何防止这种情况并获得相同的答案(成功或不成功),而不管密码如何?

答案1

一个目录可以有多个符号链接指向它,但它只有一个真正的父目录,与符号链接无关。

所以你/sys/bus/pathto_foo包含两个符号链接:

lrwxrwxrwx 1 root root    0 21 foo1 -> /sys/some/where/foo1
lrwxrwxrwx 1 root root    0 21 foo2 -> /sys/else/where/foo2

当你cd处于pathto_foo

  • 你的cat foo1/bar地图到cat /sys/some/where/foo1/bar
  • 你的cat foo2/bar地图到cat /sys/else/where/foo2/bar

当您执行 a 时,您的实际工作目录实际上cd foo1不会是,尽管 shell (/sys/bus/pathto_foo/foo1/sys/some/where/foo1并且只有外壳)会记住您将其称为/sys/bus/pathto_foo/foo1

现在,如果您执行cat ../foo1/bar,..引用/sys/some/where/,并且由于符号链接和它指向的实际目录都被方便地命名foo1,因此完整路径将/sys/some/where/foo1/bar如预期的那样。

如果您尝试cat ../foo2/bar,它现在会映射到/sys/some/where/foo2/bar,但 中 没有foo2子目录/sys/some/where

实际情况foo2是,/sys/else/where/foo2位于目录树的完全不同的分支中。

您用来到达此处的符号链接位于/sys/bus/pathto_foo,即不是实际的 ../sys/some/where/foo1

当您执行 a 时,现代和大多数 POSIX 兼容 shellcd ..的默认设置是执行 abash逻辑的转移到父目录,即截掉用户到达当前目录的路径的最右边元素,然后更改为该路径

大多数其他程序将“父目录”的概念简单地理解为“..文件系统提供的目录条目”,它指的是目录的身体的父母。

命令cd实际上bash有两个选项,-L-P,用于明确请求要切换到的路径的逻辑或物理解释。如果您未指定任一选项,则内置默认值的行为就像-L已指定一样,因此请按照上述操作。如果-P使用该选项,该cd命令的行为就像所有其他程序一样,并且每当..使用时都会更改为物理父目录。

如果您不喜欢 shell 的这个(错误)功能,可能有一种特定于 shell 的方法可以禁用它。对于bashshell,将set -P或添加set -o physical到您的~/.bashrc或类似的 shell 启动脚本将使 bash 的行为就像所有 cd 命令都具有该-P选项,除非-L显式使用该选项。

相关内容