デバッグ
前回、以下の様なスクリプトを作成しました。
#!/bin/bash
V_OPTION=$1
if test ${V_OPTION} = "bash"
then
echo "Hello bash World!!"
elif test ${V_OPTION} = "Linux"
then
echo "Hello Linux OS!!"
fi
要件は以下の2点
・第一オプションが「bash」だったら「Hello bash World!!」と表示する。
・第一オプションが「Linux」だったら「Hello Linux OS!!」と表示する。
確かに要件を満たしているので、前回のスクリプトでも正解と言えない事もありません。
ですが、このスクリプトには問題点がいくつかあります。
まずは1つ目の問題から
・例外処理がされていない。
上記2つの要件を満たしているのですが、それ以外のパターンの事が一切考えられていません。
例えば、「bash」と「Linux」以外のオプションだった場合、どのような動作をするでしょうか?
# ./helloworld3.sh bsd # # ./helloworld3.sh linux # # ./helloworld3.sh ./helloworld3.sh: line 4: test: =: unary operator expected ./helloworld3.sh: line 7: test: =: unary operator expected #
オプションに「bsd」や「linux」とつけてみました。何も表示されませんね。
オプションを何もつけなかった場合はどうでしょう。何やらエラーが出力されています。
この様に、想定している事以外の結果を「例外」と言い、この例外に関する処理を「例外処理」と言います。
今回のスクリプトの場合、「bsd」と「linux」が引数付与された場合の動作は想定通りとしても
最低限、引数が付与されなかった時、エラーが出力される事は避けるべきです。
2つ目の問題点
・if文の動作が何やらおかしい
オプションを何もつけずに動かした場合、以下の様なエラーが発生していました。
./helloworld3.sh: line 4: test: =: unary operator expected ./helloworld3.sh: line 7: test: =: unary operator expected
このエラーはなんでしょうか?
4行目と7行目がおかしい様ですが、パッと見ただけでは判りませんね。
こういう時は、詳細な処理ログを見れば判る時が多々あります。
bashスクリプトでは、詳細な処理ログを「-x」オプション付与によって出力してくれます。
スクリプト1行目の
#!/bin/bash
を
#!/bin/bash -x
に変更し、スクリプトを実行してみましょう。
まずは正常動作時のログから
# ./helloworld3.sh bash + V_OPTION=bash + test bash = bash + echo 'Hello bash World!!' Hello bash World!! #
次は、オプションを何もつけなかった時のログ
# ./helloworld3.sh + V_OPTION= + test = bash ./helloworld3.sh: line 4: test: =: unary operator expected + test = Linux ./helloworld3.sh: line 7: test: =: unary operator expected #
やはり判定文の所がおかしいですね。test文で比較対象となるべき文字列がなにもありません。
4行目と7行目はどの様な判定文を書いていたでしょうか?
#!/bin/bash -x
V_OPTION=$1
if test ${V_OPTION} = "bash"
then
echo "Hello bash World!!"
elif test ${V_OPTION} = "Linux"
then
echo "Hello Linux OS!!"
fi
大体想像つきましたか?
本来、第一オプションが格納されるはずの「V_OPTION」変数に何も格納されていないので、それを比較しようとして動作がおかしくなっているようです。
bashの変数は文字列と数字を格納する事ができますが、何も格納されていないこの状態の時、 変数内には「null」が格納されています。数字でも文字列でも無い、敢えて言うならば「何も無い」という状態です。
「何も無い」という状態と「bash」や「Linux」という文字列を比較した場合、比較対象が真か偽の判断がつかない為、エラーが出力されている事になります。
では、この2点の問題を修正しましょう。
1点目の問題点を修正する為には、「例外処理」を加えるだけで大丈夫です。
if文の例外処理はelse以後に記入します。
2点目の問題点の修正方法は「変数(実行時に付与されたオプション)が文字列である」という事を明確にする事で大丈夫です。
「echo」文でやっている通り、文字列を出力する場合、文の最初と最期に「"」を付けて括っています。
変数の場合も、文字列を扱う場合、「"」で変数を括る事により、文字列だと言うことを明示的にする事ができます。
それでは、以下の様にスクリプトを修正し、実行してみましょう。
#!/bin/bash
V_OPTION=$1
if test "${V_OPTION}" = "bash"
then
echo "Hello bash World!!"
elif test "${V_OPTION}" = "Linux"
then
echo "Hello Linux OS!!"
else
echo "Hello World!!"
fi
# ./helloworld3.sh bash Hello bash World!! # ./helloworld3.sh Linux Hello Linux OS!! # ./helloworld3.sh bsd Hello World!! # ./helloworld3.sh linux Hello World!! # ./helloworld3.sh Hello World!! #
上記の様に表示されましたか?
「bash」と「Linux」以外のオプション、もしくはオプションが付かなかった時の動作として、「Hello World!!」と出力するようにしてみました。
では、オプションに何も渡されなかった時の処理ログを見てみましょう。
スクリプト1行目を
#!/bin/bash -x
に変更し、オプションを付与しないでスクリプトを実行してみましょう。
# ./helloworld3.sh + V_OPTION= + test '' = bash + test '' = Linux + echo 'Hello World!!' Hello World!!
文字列の判定文では変数を「"」で括るようにしました。これによって変数に格納されているのは「null」ではなく空文字列と判断され、
処理ログを見ても判る通り、判定が可能となります。
これでひとまず、このスクリプトのデバッグ処理は終了です。
