1. ホーム
  2. bash

[解決済み] Bashスクリプトからプログラムが存在するかどうかを確認するにはどうすればよいですか?

2022-03-17 14:03:14

質問

プログラムが存在するかどうかを、エラーを返して終了するか、スクリプトを続行するかのどちらかの方法で検証するにはどうしたらよいでしょうか?

簡単なようで、ずっと困っているんです。

どのように解決するのか?

回答

POSIX互換です。

command -v <the_command>

使用例です。

if ! command -v <the_command> &> /dev/null
then
    echo "<the_command> could not be found"
    exit
fi

Bashに特化した環境用。

hash <the_command> # For regular commands. Or...
type <the_command> # To check built-ins and keywords

説明

避ける which . ほとんど何もしないのに起動する外部プロセスであるだけでなく(つまり hash , type または command 外部コマンドの効果はシステムによって異なることが多いのですが、ビルトインは実際にやりたいことをやってくれます。

なぜ気にするのか?

  • 多くのオペレーティングシステムでは which その は、終了ステータスさえも設定しない を意味します。 if which foo はそこでさえ機能せず 常に と報告します。 foo が存在しない場合でも、存在することになります (一部の POSIX シェルでは hash もあります)。
  • 多くのオペレーティングシステムでは which は、出力を変更したり、パッケージマネージャにフックしたりするような、カスタムで邪悪なことをします。

だから which . 代わりに、これらのいずれかを使用します。

$ command -v foo >/dev/null 2>&1 || { echo >&2 "I require foo but it's not installed.  Aborting."; exit 1; }
$ type foo >/dev/null 2>&1 || { echo >&2 "I require foo but it's not installed.  Aborting."; exit 1; }
$ hash foo 2>/dev/null || { echo >&2 "I require foo but it's not installed.  Aborting."; exit 1; }

(細かい余談ですが、一部の人は 2>&- は、同じ 2>/dev/null が、もっと短い というのは嘘です . 2>&- はFD 2を閉じますが、これは エラー これは、標準エラーに書き込むことに成功し、その出力を破棄することとは全く異なります (そして危険です!)。

もし、ハッシュバングが /bin/sh であれば、POSIXが何を言っているのかを気にする必要があります。 typehash の終了コードはPOSIXであまりよく定義されていません。 hash は、コマンドが存在しないのに正常に終了することが確認されています (この現象は type を使用します。) command の終了ステータスはPOSIXできちんと定義されているので、おそらくこれを使うのが一番安全でしょう。

スクリプトで bash しかし、POSIX のルールはもう重要ではなく、両方の typehash は、完全に安全に使えるようになります。 type を持つようになりました。 -P を検索すると PATHhash を使用すると、コマンドの位置がハッシュ化されるという副作用があります (次回使用時の検索が速くなります)。これは通常、実際に使用するためにその存在を確認することになるので、良いことです。

簡単な例として、次のような関数を実行します。 gdate が存在する場合、それ以外の場合は date :

gnudate() {
    if hash gdate 2>/dev/null; then
        gdate "$@"
    else
        date "$@"
    fi
}

充実した機能を持つ代替品

を使用することができます。 スクリプトコモン を使用することで、あなたのニーズに応えることができます。

何かがインストールされているかどうかを確認するには、次のようにします。

checkBin <the_command> || errorMessage "This tool requires <the_command>. Install it please, and then run this tool again."