シェルスクリプトで条件式を書く場合、一般的なプログラミング言語と同じように if
と記述することで判定処理を行うことができます。
例えば、ホームディレクトリ配下に「 .profile
」が存在するかをチェックする場合はこんな感じです。
if [ -e $HOME/.profile ] ; then
echo ".profile is exists"
fi
つい最近まで「シェルスクリプトの if
は test
コマンドの実行結果を判定している」という意味がよくわかっていませんでした。
if
に記述している条件式はこのようにコマンドラインで直接実行できるということを知り、ようやく理解できました。
if
というのは条件式に記述している test
コマンドを実行した際の終了ステータスを判定しているんですね。
$ [ -e $HOME/.profile ]
$ echo $?
0
[ ]
は test
コマンドのエイリアスなので、↑の if
の条件式は test
コマンドでこのように書き換えることができます。
if test -e $HOME/.profile ; then
echo ".profile is exists"
fi
当然、コマンドラインでもこのように実行することができます。
$ test -e $HOME/.profile
$ echo $?
0
man test
を見てみると、「使い方」としてこのような記述があるので、 test
と [ ]
は同義であることがわかります。
SYNOPSIS
test EXPRESSION
test
[ EXPRESSION ]
[ ]
[ OPTION
もう一点、最近知ったことがあって、 if
は test
コマンドでしか判定できないわけではなくて、条件式の部分に test
以外のコマンドを記述することも可能だということです。
つまり、このように ls
や grep
といったコマンドを書くことができます。
if ls $HOME/.profile 1>/dev/null 2>&1 ; then
echo ".profile is exists"
fi
if grep -q 'BASH_VERSION' $HOME/.profile ; then
echo "BASH_VERSION found"
fi
結論としては、こんな感じですかね。
- シェルスクリプトの
if
は条件式のコマンドを実行した際の終了ステータスを判定している。 - シェルスクリプトの
if
は一般的にtest
コマンドで判定を行うが、test
以外のコマンドを利用することも可能。
おまけ
man builtins
を見ると、 SYNOPSIS
に test
、 [
が記載されているので、それぞれBashのビルトインコマンドだということがわかりますが、
SYNOPSIS
bash defines the following built-in commands: :, ., [, alias, bg, bind, break,
builtin, case, cd, command, compgen, complete, continue, declare, dirs, disown,
echo, enable, eval, exec, exit, export, fc, fg, getopts, hash, help, history, if,
jobs, kill, let, local, logout, popd, printf, pushd, pwd, read, readonly, return,
set, shift, shopt, source, suspend, test, times, trap, type, typeset, ulimit, umask,
unalias, unset, until, wait, while.
which
で見てみると、それぞれ単体のコマンドとしても存在していることがわかります。 /usr/bin/[
ってなんだよって感じですね。
$ which test
/usr/bin/test
$ which [
/usr/bin/[