当 cwd 是指向目录的符号链接时,..(点点)如何在 bash 中解析

Eri*_*nes 5 linux bash permissions

考虑以下文件夹结构:

.
??? test1
?   ??? nested1
?   ??? testfile11
?   ??? testfile12
??? test2
    ??? nested1 -> /path/to/dir/test1/nested1
    ??? testfile21
Run Code Online (Sandbox Code Playgroud)

test2/nested1是目录的符号链接test1/nested1。我希望,如果是 cwd,..会解析为test2. 但是,我注意到了这种不一致:

$ cd test2/nested1/
$ ls ..
nested1  testfile11  testfile12
$ cd ..
$ ls
nested1  testfile21
Run Code Online (Sandbox Code Playgroud)

touch也表现得像lstest1.

为什么..作为cd引用符号链接的父级的参数,而(所有?)其他人引用链接目录的父级?是否有一些简单的方法可以强制它引用相对于符号链接的路径?即“相反”的readlink

# fictional command
ls $(linkpath ..)
Run Code Online (Sandbox Code Playgroud)

编辑:使用 bash

sch*_*ily 6

命令cdpwd有两种操作模式。

  • -L 逻辑模式:符号链接未解析

  • -P 物理模式:在执行操作之前解析符号链接

这里要知道的重要一点是,它cd ..不会调用系统调用chdir(".."),而是缩短$PWDshell 的变量,然后 chdirs 到该绝对路径。

如果处于物理模式,这与调用 相同chdir(".."),但处于逻辑模式时,这是不同的。

这里的主要问题是:POSIX 决定使用不太安全的逻辑模式作为默认值。

如果您调用cd -P而不是仅仅调用cd,那么在操作之后chdir(),返回值将getcwd()被放入 shell 变量中$PWD,并且以下内容cd ..将带您到达当前目录物理上的目录。

那么为什么 POSIX 默认的安全性较差呢?

如果您在 POSIX 默认模式下跨越了符号链接并执行以下操作:

ls ../*.c
cd ..
rm *.c
Run Code Online (Sandbox Code Playgroud)

您可能会删除与之前命令列出的文件不同的文件ls

如果您喜欢更安全的物理模式,请设置以下别名:

alias cd='cd -P'
alias pwd='pwd -P'
Run Code Online (Sandbox Code Playgroud)

由于当使用多个选项-L并且-P最后一个选项获胜时,您仍然可以获得其他行为。

历史背景:

Bourne Shell 和 ksh88 确实同时获得了目录跟踪代码。

Bourne Shell 确实获得了更安全的物理行为,而 ksh88 同时确实获得了不太安全的逻辑模式作为默认值以及选项-L-P。ksh88 可能参考了 csh 行为。

POSIX 采用了 ksh88 行为,但没有讨论这是否是一个好的决定。

顺便说一句:有些 shell 无法跟踪$PWD长于 的值,PATH_MAX当您 chdir 进入绝对路径长于 的目录时,会让您发疯PATH_MAXdash就是这样一个有缺陷的外壳。