シェルスクリプトで外部コマンドの有無を確認したい
シェルスクリプトでは、実行環境にcurlやjqなどの外部コマンドが存在するかを事前にチェックし、存在しない場合はエラーメッセージを出して処理を止めたいことがある。コマンドの存在チェックにはcommandコマンドとwhichコマンドが使える。
command -v でコマンドの存在をチェックする
command -vにコマンド名を渡すと、そのコマンドが実行可能な場合はパスなどを表示し、終了ステータス0を返す。
$ command -v ls
/usr/bin/ls
$ echo $?
0
存在しないコマンドを指定した場合は何も表示せず、終了ステータスは非0になる。
$ command -v thiscommanddoesnotexist
$ echo $?
1
終了ステータスを利用すれば、if文でコマンドの存在チェックができる。
if command -v curl >/dev/null 2>&1; then
echo "curl is installed"
else
echo "curl is NOT installed"
fi
command -vはビルトインコマンドやシェル関数、エイリアスも判定対象に含む。
$ command -v cd
cd
$ shopt -s expand_aliases
$ alias ll="ls -la"
$ command -v ll
alias ll='ls -la'
which でコマンドの存在をチェックする
whichにコマンド名を渡すと、PATH上に該当する実行ファイルがある場合はそのパスを表示し、終了ステータス0を返す。
$ which ls
/usr/bin/ls
$ echo $?
0
存在しないコマンドを指定した場合は何も表示せず、終了ステータスは非0になる。
$ which thiscommanddoesnotexist
$ echo $?
1
whichもif文で存在チェックに使える。
if which curl >/dev/null 2>&1; then
echo "curl is installed"
else
echo "curl is NOT installed"
fi
whichはPATH上の実行ファイルしか探せないため、ビルトインコマンドやエイリアスは検出できない。
$ which cd
$ echo $?
1
$ alias ll="ls -la"
$ which ll
$ echo $?
1
command と which の違い
commandはシェルのビルトインコマンドである一方、whichは/usr/bin/whichのような外部コマンドとして提供される。
$ type command
command is a shell builtin
$ type which
which is /usr/bin/which
そのため、commandはどのシェルでも動作が保証されているが、whichはディストリビューションによって存在しなかったり、出力形式が異なったりすることがある。command -vはPOSIXで規定された機能であり、bashだけでなくdashのような/bin/shでも同様に使える。
$ sh -c 'command -v ls'
/usr/bin/ls
コマンドの存在チェックが目的であれば、ビルトインコマンドやエイリアスも判定でき、移植性の高いcommand -vを使うとよい。
\第一線のプログラマーの行動原理を学べる!/
