假设我有一个文件a
是到 的符号链接b
,而该文件又是到 的符号链接c
。
使用 zsh 的:A
修饰符,通配 a 将产生绝对路径,解析所有符号链接,因此将扩展到(在具有该库的系统上)a(:A)
的绝对路径。c
realpath
是否有可能获得b
(绝对或相对,但直接作为通配符的结果,而不是例如通过查看 的输出ls -l
)甚至文件达到任意符号链接深度?
Bash 的解决方案也值得了解。
答案1
您始终可以创建一个与 glob 限定符一起使用的函数+
:
$ zmodload zsh/stat $resolve() { [[ -L $REPLY ]] && stat -A REPLY +link -- ${1-$REPLY}; } $ print -r - a(+解析) 乙 $ print -r - a(+解析:a) /home/stephane/b (尽管请参阅下面的警告)
请注意,如果这样做a(+resolve+resolve)
,第二个resolve
仍将在原始文件名 ( ) 上调用,而不是在第一个( )a
的结果上调用。但是你可以这样做:resolve
b
$ print -r - a(e['resolve && resolve'])
c
将两个resolve
s 链接起来。然而(并且警告也适用于:a
上面的用法),尽管它适用于这个特定的示例,但在一般情况下这不是一个有效的事情,因为当相对路径时,符号链接的目标是相对于符号链接,而不是当前工作目录,所以如果dir/link
指向foo
,那就是文件dir/foo
,而不是foo
,所以它仅在解析当前工作目录中的符号链接时有效。
resolve
不过,如果我们改变它,那么它就会计算符号链接目标的完整路径,这将不再是一个问题:
resolve() {
local target
[[ -L $REPLY ]] &&
stat -A target +link -- ${1-$REPLY} &&
case $target in
(/*) REPLY=$target;;
(*) REPLY=${REPLY:h:a}/$target;;
esac
}
bash
没有 glob 限定符,也没有任何接口readlink()
(如内置zsh
的stat
),但在某些系统上,您会找到一个readlink
命令:
$ readlink a
b