Bashで実行されるコマンドを確認する|command -vとtype -a

ツールを入れたはずなのに見つからない、別の版が動く、端末で実行したときだけ挙動が違う。Bashでは、同じ名前でも実行ファイルのほかに組み込みコマンドや関数が選ばれるため、インストール先だけを見ても理由が分からないことがあります。

まず今のBashがその名前をどう解釈するかを調べると、PATHや設定を変更する前に手掛かりを得られます。以下はUbuntuやWSLのLinux端末など、Bashで使う例です。PowerShellや別のシェルでは、同じ名前のコマンドでも機能やオプションが異なります。

command -vで今の検索結果を見る

command -v bash

この例はbashという名前を調べるだけで、別のBashを起動する操作ではありません。たとえば/usr/bin/bashと表示されれば、現在の環境ではそのパスが見つかっています。手元のツールを調べるときは、bashをcurlやpython3などの名前に置き換えられます。

command -vは、常にファイルの絶対パスだけを返すわけではありません。組み込みや関数なら名前、エイリアスが有効な場面では定義の説明が出ることもあります。表示された文字列を、そのまま実行ファイルのパスだと決めないのがポイントです。

type -aで同じ名前の候補を並べる

type -a bash

PATH上に同じ名前の実行ファイルが複数あると、候補が複数行で表示されます。/usr/bin/bashと/bin/bashが並ぶ環境もありますが、別の版が二つ入っているとは限りません。リンクなどで同じ実体を指す構成もあるため、行数だけで重複インストールと判断しないでください。

Bashのtype -aは、エイリアス、予約語、関数、組み込み、実行ファイルといった候補を調べられます。対話的なBashで設定したエイリアスや関数が、PATH上のファイルより先に使われる場合もあります。非対話のスクリプトではエイリアス展開が通常無効なので、端末とスクリプトで結果が違うときは、その実行環境で調べることが大切です。

組み込みと実行ファイルを見分ける

type -t printf
type -a printf

最初の出力がbuiltinなら、Bashの組み込みとして認識されています。次のtype -aでは、組み込みに加えて/usr/bin/printfなどが見つかる場合があります。名前が同じでも、組み込みと外部コマンドでは対応オプションなどが異なることがあります。

type -tの表示 読み取れること
builtin Bashの組み込みコマンド
file 実行ファイルとして見つかった候補
function シェル関数
alias 有効なエイリアス
keyword Bashの予約語

これらは現在のシェルから見た分類です。別の端末、別ユーザー、WSLの別ディストリビューションでは、PATHや読み込む設定が違う可能性があります。実際に困っている処理と同じ環境で比べると、関係のない設定を直す回り道を減らせます。

見つかったかを条件分岐で確かめる

if command -v curl >/dev/null 2>&1; then
  printf 'curl is available\n'
else
  printf 'curl was not found\n'
fi

curlという名前が見つかれば前者、見つからなければ後者を表示します。出力を捨てて終了状態で判定しているため、説明文やパスの文字列を解析する必要がありません。この例自体はcurlで通信を行いません。

名前が見つかったことは、目的の版であること、接続が成功すること、指定したオプションが使えることまで保証しません。関数やエイリアスを検出する場合もあります。まず見つかった候補と種類を読み取り、必要に応じて対象ツールの公式な版確認や目的の処理へ進めると、確認した範囲を取り違えにくくなります。

シェルスクリプトのファイルは見つかるのに実行に失敗する場合は、CRLF・LFとshebangの確認も手掛かりになります。Windows上とWSL内ではツールの所在や設定が別になるため、WSLのLinux環境の確認も合わせて進められます。

参考資料