[解決済み] Bashスクリプトからプログラムが存在するかどうかを確認するにはどうすればよいですか?
質問
プログラムが存在するかどうかを、エラーを返して終了するか、スクリプトを続行するかのどちらかの方法で検証するにはどうしたらよいでしょうか?
簡単なようで、ずっと困っているんです。
どのように解決するのか?
回答
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が何を言っているのかを気にする必要があります。
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."
関連
-
[解決済み] Bashスクリプトで引数を反復処理する方法
-
[解決済み] Bashスクリプトのソースディレクトリをスクリプト自体から取得するにはどうすればよいですか?
-
[解決済み] Bashシェルスクリプトでディレクトリが存在するかどうかを確認するにはどうすればよいですか?
-
[解決済み] Bashで通常のファイルが存在しないかどうかを判断する方法を教えてください。
-
[解決済み] Bashで文字列変数を連結する方法
-
[解決済み] Bashで文字列が部分文字列を含むかどうかをチェックする方法
-
[解決済み] Bashで文字列をデリミターで分割するには?
-
[解決済み] Bashでコマンドライン引数を解析するには?
-
[解決済み] Bashで変数が設定されているかどうかを確認する方法は?
-
[解決済み] Bashシェルスクリプトの入力引数の存在確認
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Docker ubuntu イメージ - bash: man: コマンドが見つかりません。
-
[解決済み] Curl:応答を待たない[重複]。
-
[解決済み] 構文エラー:オペランドが期待される(エラーメッセージは "+")。
-
[解決済み] echoコマンドでパイピングが効かない [重複]。
-
[解決済み] bash スクリプトを実行しているドッカーエントリーポイントが "パーミッション拒否" になる
-
npm err インストールエラーの解決策
-
[解決済み] condaのアップデート後、ターミナルのプロンプトから(base)を削除する方法
-
[解決済み] ターミナルでbashスクリプトを実行するにはどうすればよいですか?
-
[解決済み] bashの"-ne "はどういう意味ですか?
-
[解決済み】シェルスクリプトにコマンドが存在するかどうかを確認するにはどうすればいいですか?重複