Bash
在 zsh/Bash 中通配時部分解析/遵循符號連結
假設我有一個文件,該文件
a
是指向 的符號連結b
,而該文件又是指向 的符號連結c
。使用 zsh 的
:A
修飾符,通配 a 將產生一個絕對路徑,解析所有符號連結,因此a(:A)
將擴展為c
(在具有該realpath
庫的系統上)的絕對路徑。是否有可能獲得
b
(絕對的或相對的,但直接作為萬用字元的結果,而不是例如通過查看 的輸出ls -l
)甚至是任意符號連結深度的文件?Bash 的解決方案也很有趣。
您始終可以創建一個與
+
glob 限定符一起使用的函式:$ zmodload zsh / 統計 $ resolve() { [[ -L $REPLY ]] && stat -A REPLY +link -- ${1-$REPLY}; } $ print -r -a(+resolve) b $ print -r - a(+resolve: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
so 它計算符號連結目標的完整路徑: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
’sstat
內置),但在某些系統上,您會找到一個readlink
命令:$ readlink a b