这种情况经常发生在/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/foo1
或pathto_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 的方法可以禁用它。对于bash
shell,将set -P
或添加set -o physical
到您的~/.bashrc
或类似的 shell 启动脚本将使 bash 的行为就像所有 cd 命令都具有该-P
选项,除非-L
显式使用该选项。