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 then
then
」というキーワードも test
の引数であると見做されてしまう。
そういうわけで、if test -f $my_file; then
と書いて、コマンドと then
を「;
」で区別してあげる必要がある。
次に if [ -f $my_file ]; then
だけど、[ ... ]
が test
コマンドの糖衣構文(シンタックスシュガー)だってことをまず知ろう。
すると ;
が then
の前に必要なのはもう分かるよね。
じゃあ「[
」と「]
」の前後に半角スペースが一つ以上必要なのはなぜ?
それは依然 [ ... ]
もコマンドなんだ(見た目は制御構造の一部みたいだけどね)。
シェルスクリプトでは、コマンドや引数同士は半角スペースで区切らなきゃいけない。
だから形は変われど [ ... ]
はコマンドだから、内包するコマンドや引数との間にスペースを必要とする。
念の為に付け加えておくと、[ ... ];
この最後のセミコロンは改行と等しくひとつのコマンド呼び出しの終了を表しているだけなので、「]
」と「;
」の間にスペースは不要だ。
参考: