エラーを返して終了するか、スクリプトを続行するかのいずれかの方法で、プログラムが存在することを検証するにはどうすればよいでしょうか?
簡単なことのように思えますが、困惑しています。
ベストアンサー1
答え
POSIX 互換:
command -v <the_command>
使用例:
if ! command -v <the_command> &> /dev/null
then
echo "<the_command> could not be found"
exit 1
fi
Bash 固有の環境の場合:
hash <the_command> # For regular commands. Or...
type <the_command> # To check built-ins and keywords
説明
は避けてくださいwhich
。これは、ほとんど何もしないために起動する外部プロセスであるだけでなく ( hash
、type
やなどの組み込みコマンドの方command
がはるかに安価であることを意味します)、組み込みコマンドに頼って実際に必要な処理を実行できる場合もありますが、外部コマンドの効果はシステムによって簡単に異なる場合があります。
なぜ気にするのですか?
- 多くのオペレーティング システムには、終了ステータスを設定しない がある
which
ため、 はそこでは動作せず、が存在しない場合でも が存在すると常に報告されます(一部の POSIX シェルも に対してこれを行うようです)。if which foo
foo
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
が短いと言う人もいるが、これは誤り。FD 2>&-
2 を閉じると、stderr に書き込もうとしたときにプログラムでエラーが発生します。これは、正常に書き込みを行って出力を破棄すること (危険!) とはまったく異なります。)
ハッシュバンが である場合/bin/sh
、POSIX の規定に注意する必要があります。type
およびhash
の終了コードは POSIX によって十分に定義されておらず、hash
コマンドが存在しない場合に正常に終了することがわかります ( ではtype
まだこれを見たことがありません)。command
の終了ステータスは POSIX によって十分に定義されているため、おそらくこれを使用するのが最も安全です。
ただし、スクリプトで を使用する場合bash
、POSIX ルールは実際にはもう重要ではなくなり、 と の両方type
がhash
完全に安全に使用できるようになります。には のみを検索するが含まれるようtype
になり、副作用としてコマンドの場所がハッシュ化されます (次回使用するときに検索を高速化するため)。これは、実際に使用するためにその存在を確認する可能性が高いため、通常は良いことです。-P
PATH
hash
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."