考虑以下文件夹结构:
.
├── test1
│ ├── nested1
│ ├── testfile11
│ └── testfile12
└── test2
├── nested1 -> /path/to/dir/test1/nested1
└── testfile21
test2/nested1
是目录的符号链接test1/nested1
。我预计,如果是 cwd,..
会决心这样做test2
。但是,我注意到这种不一致:
$ cd test2/nested1/
$ ls ..
nested1 testfile11 testfile12
$ cd ..
$ ls
nested1 testfile21
touch
其行为也类似于ls
在 中创建文件test1
。
为什么..
作为参数cd
引用符号链接的父级,而(全部?)其他引用链接目录的父级?有没有一些简单的方法来强制它引用相对于符号链接的路径?即“相反” readlink
?
# fictional command
ls $(linkpath ..)
编辑:使用 bash
答案1
命令cd
和pwd
有两种操作模式。
-L 逻辑模式:符号链接未解析
-P 物理模式:在执行操作之前解析符号链接
这里要知道的重要一点是,它cd ..
不会调用系统调用chdir("..")
,而是缩短$PWD
shell 的变量,然后 chdirs 到该绝对路径。
如果处于物理模式,这与调用 相同chdir("..")
,但处于逻辑模式时,这是不同的。
这里的主要问题是:POSIX 决定使用不太安全的逻辑模式作为默认值。
如果您调用cd -P
而不是仅仅调用cd
,那么在chdir()
操作之后,返回值将getcwd()
被放入 shell 变量中$PWD
,并且以下内容cd ..
将带您到达当前目录物理上的目录。
那么为什么 POSIX 默认的安全性较差呢?
如果您在 POSIX 默认模式下跨越了符号链接并执行以下操作:
ls ../*.c
cd ..
rm *.c
您可能会删除与之前命令列出的文件不同的文件ls
。
如果您喜欢更安全的物理模式,请设置以下别名:
alias cd='cd -P'
alias pwd='pwd -P'
由于当使用多个选项-L
并且-P
最后一个选项获胜时,您仍然可以获得其他行为。
历史背景:
Bourne Shell 和 ksh88 确实同时获得了目录跟踪代码。
Bourne Shell 确实获得了更安全的物理行为,而 ksh88 同时确实获得了不太安全的逻辑模式作为默认值以及选项-L
和-P
。 ksh88 可能参考了 csh 行为。
POSIX 采用了 ksh88 行为,但没有讨论这是否是一个好的决定。
顺便说一句:有些 shell 无法跟踪$PWD
长于 的值,PATH_MAX
当您 chdir 进入绝对路径长于 的目录时,会让您发疯PATH_MAX
。dash
就是这样一个有缺陷的外壳。
答案2
需要阅读的重要论文是http://doc.cat-v.org/plan_9/4th_edition/papers/lexnamesRob Pike 谈论这个问题。
您还需要指定您的 shell,例如 bash 跟踪它对当前目录的想法,如果您说它cd ..
只是切断最后一个组件并在那里进行更改,而不是实际发出chdir("..")
系统调用。
抱歉现在手机上,稍后编辑...
答案3
您可能想尝试 -pa ,它将遵循物理目录结构而不遵循符号链接