「どれ」、しかしすべて

「どれ」、しかしすべて

おそらく、ほとんどの人がこのwhichコマンドに精通しているでしょう、そして私もかなり頻繁に使用します。私のパスでは、どのコマンドが最初のものであるかだけでなく、どのくらいのコマンドがあり、どこにいるのか疑問に思う状況に直面しました。みんなパス内のすべてのコマンドは次のとおりです。どのマニュアルページを試してみましたが(この言葉を入力するとman which笑いになります)、何も見られませんでした。

答え1

一部のシステムではwhich -aすべての一致を表示します。シェルがbashまたはzsh1の場合は、次のものを使用できますtypetype foo最初の一致項目の表示とtype -a fooすべての一致項目の表示。これら3つのコマンドはほとんど同じことをtype行います。シェルとオペレーティングシステムの違いは、可用性、オプション、およびレポートの内容です。常に使用可能で、すべての可能なコマンドに似た名前(エイリアス、キーワード、シェル組み込み、関数、および外部コマンド)を表示します。whichwhencetype

すべての一致を表示する完全に移植可能な唯一の方法は、$PATH自分自身を解析することです。これを行うシェルスクリプトは次のとおりです。これをシェル関数にする場合は、関数本体を括弧で囲んでから(に変更すると関数がエスケープされないように)にIFS変更します。set -fexitreturn

#!/bin/sh
set -f       # disable globbing
IFS=:        # break words at : only
not_found=1
for d in $PATH; do
  if [ -f "$d/$x" ] && [ -x "$d/$x" ]; then
    printf '%s\n' "$d/$x"
    not_found=0
  fi
done
exit $not_found

または、ドキュメントによると、ksh 93ですが、ksh 93s + 2008-01-31は、試みたときにのみ最初の一致を印刷します

答え2

--allまたは-aフラグは、パス内のすべての一致とエイリアスを表示します(少なくともFedora、Ubuntu、およびCentOSでは)。

which -a which

AIX および Solaris では、次の利点が得られます。

echo "$PATH" | sed -e 's/:/ /g' | \
while read -r p; do find "$p" -type f -name "which"; done

答え3

whichサポートがない場合、または利用可能な場合は-a直接whenceリリースしてください。

#!/bin/sh -f

IFS=":"
for PART in $PATH
do
  if test -x "$PART/$1"
  then
    echo $PART/$1
  fi
done

答え4

kshとzshには「whence」がシェルとして組み込まれています。 whence -azshで好きなことをします。

 7:27AM 7 % whence -a cat
/usr/bin/cat
/bin/cat
/usr/bin/cat
/bin/cat

zshでPATHをクリーンアップする必要がありますが、重複した項目がたくさんあります。whence -akshでは、状況は異なる動作をします。

$ whence -a cat
cat is a tracked alias for /usr/bin/cat

私はこれが潜在的に有用な行動のように見えると言わなければなりません。

関連情報