bash 和它的自动完成器在 .. 目录符号链接的含义上存在冲突

bash 和它的自动完成器在 .. 目录符号链接的含义上存在冲突

在我的主目录中,创建到目录的/home/regis符号链接并执行操作后,我在 bash 及其自动完成器之间发生了冲突,导致了冲突。LINKDIR/SUBDIRcd LINK..

对于 bash 自动完成器,..会导致/home/regis,正如用户所期望的,因为 pwd 显示/home/regis/LINK,就像使用 PS1 时的提示一样\w

对于 bash 本身,..导致DIR../..导致/home/regis,这意味着它正在使用真实路径/home/regis/DIR/SUBDIR,如 所示pwd -P

这里应该期待哪种行为?我在这里做错了什么吗?

/home/regis$ 触摸文件
/home/regis$ mkdir -p DIR/SUBDIR
/home/regis$ ln -s 目录/子目录链接
/home/regis$ cd 链接

/home/regis/LINK$ ls ../FI # 使用 TAB 的自动完成在这里成功
/home/regis/LINK$ ls ../FILE # 但自动完成的命令将在此处失败
ls:无法访问“../FILE”:没有这样的文件或目录
/home/regis/LINK$ ls ../../FILE # 命令成功
文件

$ bash -版本
GNU bash,版本 5.0.17(1)-release (x86_64-pc-linux-gnu)

答案1

对于 bash 本身,..导致DIR../..导致/home/regis

通常不会...

/home/regis/LINK$ ls ../FILE # but autocompleted command will fail here
ls: cannot access '../FILE': No such file or directory
/home/regis/LINK$ ls ../../FILE # command succeeds

...但这不是 Bash,这是ls.

问题是 Bash 试图变得用户友好,当您cd通过符号链接时,它会在内部记住您到达那里所采取的路径。然后cd ..在 Bash 中使用该路径执行例如操作,这样cd LINK; cd ..您就可以回到开始的地方。

但它ls是一个外部进程,它不知道任何这些,并且只看到自己在某个工作目录中运行,该工作目录就在/home/regis/DIR/SUBDIR这里,无论cd使用什么命令到达那里。好吧,实际上ls只是将路径名传递给操作系统,操作系统也不关心,而是仅使用原样的工作目录以及..文件系统中的条目。

如果您cd -P LINK改为使用,shell 将禁用该特殊行为,并且您也会看到与/home/regis/DIR/SUBDIRshell 中一样的路径。通常人们不会打扰,因为大多数时候它工作得很好,只要你不尝试“向上​​”超过符号链接指向的点。

另请参阅我之前的回答 https://unix.stackexchange.com/a/739426/170373对于同一主题的“漂亮”ASCII 图表。

相关内容