どのコマンドの出力順序が正しいですか?

どのコマンドの出力順序が正しいですか?

bash ではwhichパスが順番に返されますが、zsh では順序が異なります。

現在、私は主に zsh を使用していますが、zsh で適切な出力順序を取得するにはどうすればよいでしょうかwhich? なぜ異なるのでしょうか? 順序はパスと一致すると予想していました。

私の道は次のとおりです:/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

答え1

次のように定義しましたwhich:

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

ls出力時にファイル名を辞書順にソートし、後に来るのは/usr/local/bin/git/usr/bin/gitl後に来ますbあなたの地域で。

の GNU 実装には、そのソートを無効にするオプションlsがあります。-U

あなたのコマンドは、オプションを渡されたとき/usr/bin/whichに見つかったすべてのコマンド名のパスを出力するもののようです。組み込みコマンドを使用すると、¹ を使用して同じことを行うことができます。$PATH-azshwhence -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組み込みzshがありますwhich


¹ ただし、/usr/bin/whichzsh の組み込みとは異なり、whichエイリアス、関数、組み込み、実行可能ファイルのテーブルさえも無視するため、シェルがどのコマンドを実行するかを必ずしも教えてくれるわけではありません$hash「which」を使わないのはなぜですか? では、何を使うべきでしょうか?

関連情報