[Sy] シェルスクリプトのif文の条件式で「command not found」となるやりがちなミスに気をつけよう
シェルスクリプトでif文の条件式などに使うif [・・・]; then
という構文ですが、あることに気をつけないとcommand not found
と怒られます。
たまにシェルスクリプトを書くとついつい同じミスをやってしまいます。
if文の条件式で command not found となってしまう
例えば、引数を一つ受け取ってその引数がabc
と一致するかどうか判定して、一致したらtrue
、一致しなかったらfalse
と出力するだけの単純なtest.sh
というシェルスクリプトを考えます。
[test.sh]
# !/bin/sh
if [$1 = "abc"]; then
echo "true"
else
echo "false"
fi
一見特に問題なさそうですが、この状態で実行すると、
$ ./test.sh abc
./test.sh: line 3: [abc: command not found
false
となります。
何がいけないのか?
答えを先に言っちゃうと、if文の条件式のところはこう書かないといけません。
[test.sh]
# !/bin/sh
if [ $1 = "abc" ]; then
echo "true"
else
echo "false"
fi
これでエラーが起きなくなります。
$ ./test.sh abc
true
$ ./test.sh abd
false
修正したのは、[$1 = "abc"]
となっていた部分を[ $1 = "abc" ]
と、スペースを入れてあげただけです。
実はシェルスクリプトのif文などで使われる[・・・];
という部分は、 testコマンド というコマンドのもう一つの記述方法なんです。
どういうことかというと、先ほどのスクリプトは以下のように書き換えることができます。
[test.sh]
# !/bin/sh
if test $1 = "abc"; then
echo "true"
else
echo "false"
fi
testコマンドは条件式の判定を行い、trueかfalseを返す ので、if文などの構文で使われます。ただ、上のようにif test $1 = "abc"
と書くとちょっと見づらいですよね?
なので[
という別の記述もできるようになっていて、[
でtestコマンドを書いた場合は条件式の最後に]
をつけて閉じてあげる必要があります。
最初のエラーは、[
というコマンドとして処理しないといけないのに、変数$1
の前にスペースを入れていなかったので、 [$1
というコマンドとして認識されてしまい、そんなコマンドはないよ!と怒られちゃったわけですね。
PHPやJavaScriptのような一般的なスクリプト言語では条件式を()
で囲みますが、(
の後ろと)
の前にスペースがあってもなくても当然問題ありません。
そのノリでシェルスクリプトを書くと、このエラーが出るので注意しましょー。