
if 制御構造は次のように複数の書き方がある(動作は全て同じ)。
#! /bin/sh
my_file="some.file"
# if 1
if test -f $my_file
then
echo "$my_file Exists."
else
echo "Not Found ${my_file}."
fi
# if 2
if test -f $my_file; then
echo "$my_file Exists."
else
echo "Not Found ${my_file}."
fi
# if 3
if [ -f $my_file ]; then
echo "$my_file Exists."
else
echo "Not Found ${my_file}."
fi
丸暗記でもいいけど、意味を理解したほうがベターだ。
まず if は直後にくる「コマンド」の返り値で真偽を判断する。
そう、上の例で言えば test -f $my_file は単にコマンド呼び出しなのだ。
コマンドを呼ぶときの原則を思い出そう。
シェルスクリプトは行指向のインタプリタを使ってるから「改行」には「コマンドの入力を終了したよ」という、行を改める以上の意味がある(だから、コマンドが複数行にまたがるときは改行する前に「\」を入れるよね)。
test -f $my_file はこれでひとつのコマンドなわけだから、もし if test -f $my_file thenthen」というキーワードも test の引数であると見做されてしまう。
そういうわけで、if test -f $my_file; then と書いて、コマンドと then を「;」で区別してあげる必要がある。
次に if [ -f $my_file ]; then だけど、[ ... ] が test コマンドの糖衣構文(シンタックスシュガー)だってことをまず知ろう。
すると ; が then の前に必要なのはもう分かるよね。
じゃあ「[」と「]」の前後に半角スペースが一つ以上必要なのはなぜ?
それは依然 [ ... ] もコマンドなんだ(見た目は制御構造の一部みたいだけどね)。
シェルスクリプトでは、コマンドや引数同士は半角スペースで区切らなきゃいけない。
だから形は変われど [ ... ] はコマンドだから、内包するコマンドや引数との間にスペースを必要とする。
念の為に付け加えておくと、[ ... ]; この最後のセミコロンは改行と等しくひとつのコマンド呼び出しの終了を表しているだけなので、「]」と「;」の間にスペースは不要だ。
参考:
