Which

哪個命令輸出順序是什麼?

  • October 23, 2021

在 bash 中,我看到which按順序返迴路徑,但在 zsh 中它具有不同的順序。

我現在主要使用 zsh,如何which在 zsh 中獲得正確的輸出順序?為什麼不一樣?我希望排序與我的路徑相匹配。

我的路徑是:/usr/local/bin:/usr/bin

bash$ which -a git
/usr/local/bin/git
/usr/bin/git
zsh$ which -a git
/usr/bin/git
/usr/local/bin/git -> ../Cellar/git/2.32.0/bin/git

你碰巧which定義為:

which(){
 /usr/bin/which -a "$@" |
   xargs ls -l |
   tr -s ' ' |
   cut -d ' ' -f 9-
}

ls在輸出上按詞法對文件名進行排序,然後因為在您的語言環境中出現。/usr/**l**ocal/bin/git``/usr/**b**in/gitl****b

的 GNU 實現ls具有-U禁用該排序的選項。

您的/usr/bin/which命令似乎是在$PATH傳遞-a選項時列印找到的所有命令名稱的路徑的命令。使用zsh內置函式,您可以使用whence -pa¹ 執行相同的操作。

因此,您可以執行以下操作:

mywhich() (
 set -o pipefail
 zmodload zsh/stat
 whence -pa "$@" |
   while IFS= read -r f; do
     if [[ -L $f ]] && stat -A l +link -- $f; then
       print -r -- "$f -> $l"
     else
       print -r -- $f
     fi
   done
)

(這裡假設所有文件路徑都不包含換行符)。

在 GNU 系統上,您的更正確版本應該是:

mywhich() (
 set -o pipefail
 command which -a "$@" |
   xargs -rd '\n' ls -ndU -- |
   sed -E 's/([^ ]+ +){8}//'
)

在任何情況下,請注意它bash沒有which內置,所以那裡which的輸出與外殼無關。只有tcsh並且zshwhich內置的。


¹不過,就像您的/usr/bin/which(但與 zsh 的 builtin 相反which),它不一定會告訴您 shell 將執行哪個命令,因為它忽略了別名、函式、內置函式甚至$hash執行檔表。另請參閱為什麼不使用“which”?那該用什麼?

引用自:https://unix.stackexchange.com/questions/674470