• このエントリーをはてなブックマークに追加

【シェルスクリプト入門】その2: デバッグの方法

  • このエントリーをはてなブックマークに追加

bash
zaco muraです。

先日書いた【シェルスクリプト入門】その1: シェルスクリプト概要とHello Worldの続きになります。
今回はシェルスクリプトがうまくいかない場合、問題の箇所を見つける(デバッグする)方法について説明します。

なお、環境としてはCentOS系のOSでシェルはbashを想定しています。

今回のシェルスクリプトの内容

今回は簡単な数値計算をするスクリプトを書いてみます。
こんな感じです。(ちなみにバグありなので正しく動きません)

#!/bin/bash
HENSU1=`expr 1 + 1`
HENSU2=`expr ${HENSU1} + 1`
ANSWER=`expr ${HENSU2} * 2`
echo "ANSWER is ${ANSWER}"

シェルスクリプトの中身を簡単に解説しますと

・exprコマンドは数値計算をするコマンド
・`コマンド`のように`(バッククオート)で囲ったコマンドは行全体を実行する前に実行される
・HENSU1= でHENSU1という変数にexprの結果を代入するということ

です。ちょっとわかりづらいですかね。
言い換えるとHENSU1=`expr 1 + 1` というのは、2回コマンドが実行されます

①`expr 1 + 1`の部分が実行。 => 結果として2が出力。
②HENSU1=2の部分が実行。 => 結果としてHENSU1に2が代入。

つまりHENSU1=`expr 1 + 1` を実行することにより、HENSU1には 2 が代入されます。
(ちなみに、変数を参照するときには${}を付けます。${HENSU1}みたいな感じ)

なぜこのようにするかと言うと、expr 1+1の結果を保存しておくためです。

少し話が脱線しましたが、このシェルスクリプトは
・変数1に 1 + 1 の結果を代入 (つまり2)
・変数2に 変数1 + 1の結果を代入 (つまり2+1=3)
・変数ANSWERに 変数2 × 2の結果を代入 (つまり3×2=6)
・変数ANSWERを表示(6)

というシェルスクリプトです。

実行してみると

では早速これを実行してみます。

[root@server1 ~]# ./keisan.sh
expr: 構文エラー
ANSWER is

構文エラーとなりました。
そして本来答えが表示されるはずの部分は”ANSWER is”と空白になっています。

どこか構文エラーがありますでしょうか?例えば“はちゃんとペアになっているか?
もう一回ソースコードを見てください。

たぶん見つからないでしょう。(自分は昔めっちゃハマりました)

わからない時は、デバッグしてみましょう。

デバッグ実行

bashをデバッグするには、bash -x というコマンドで実行します。以下のようになります。

[root@server1 ~]# bash -x keisan.sh
++ expr 1 + 1
+ HENSU1=2
++ expr 2 + 1
+ HENSU2=3
++ expr 3 keisan.sh 2
expr: 構文エラー
+ ANSWER=
+ echo 'ANSWER is '
ANSWER is

いかがでしょうか。さっきより情報量が増えました。
これを見ると、どうやら”HENSU2 = 3″の部分まではうまくいってそうです。

構文エラーと表示される直前の部分、本来なら”expr 3 * 2″となっているはずの部分に”keisan.sh”という表示が入っています。これは怪しいですね

exprではかけ算は “*”(アスタリスク)で表すのですが、linuxで*は”ディレクトリにある全てのファイル”を意味します。

つまり、

expr 3 * 2

としたいところが、シェルスクリプト上では

expr 3 カレントディレクトリのファイル(keisan.sh) 2

という解釈をされているのです。当然数値計算は失敗し、構文エラーとなったということです。

どうすればうまくいくのか?

bashでは”*"のような意味がある文字を、ただの文字として解釈することを”クオートする”と言います。そしてクオートする方法は、直前に”¥”を付ければOKです。ということで、さっきのスクリプトを以下のように修正します。

#!/bin/bash
HENSU1=`expr 1 + 1`
HENSU2=`expr ${HENSU1} + 1`
ANSWER=`expr ${HENSU2} ¥* 2`
echo "ANSWER is ${ANSWER}"

では実行してみましょう。

[root@server1 ~]# ./hello.sh
ANSWER is 6

今度はうまくいきました。

このように、問題の箇所を特定するためには”bash -x “を使えば近道となります。

スポンサーリンク
Sponsords Link
  • このエントリーをはてなブックマークに追加

ZacoDesign

スポンサーリンク
Sponsords Link