第11章:デバックの手順・手法

始めに

C言語とかを少しやっていたこともあり、コンパイルエラー等でデバッグできないのはかなり辛いです。そんなわたくしの悩みを解決してくれそうな第11章。しっかりスクリプトデバッグ方法を学習したいと思います。

shコマンドでのスクリプト実行

スクリプトを実行する方法は2つ。

  • コマンドのようにスクリプトを実行する
  • shコマンドを使用して実行する
    • shコマンドの後に、スクリプトファイルを指定し、そのあとにパラメータを指定する
    • スクリプトファイルには実行権限は必要ない。
    • デバッグオプションが使用できる。

shコマンドのデバッグオプション

  • vオプション
    • シェルスクリプトが実行しようとしていることを1つ1つ表示してくれる。
    • ただし、ループの内容を1回1回表示することはない。
    • 入っている変数の内容も表示されない。
  • xオプション
    • シェルスクリプトが実際に行ったことを表示してくれる。
    • 変数の内容も表示される。
    • 実際に実行したコマンドの先頭には+マークが付く。

上記の両方を同時に使用すれば、だいたいそのシェルスクリプトの処理内容を把握できる。

スクリプト中にvオプション等を埋め込む

スクリプトの中にvオプション等を使用したいときは、スクリプト内で

set -v

と記載するだけ。
もし、有効にしたけど無効にしたいときは

set +v

と記載すればいい。

nオプション

nオプションを使用すると、シェルスクリプトの構文や整合性をチェックするだけで、実際には実行しない。

書き方の注意事項

基本的な話しかもしれませんが、間違えやすい事をまとめてくれているので、しっかり見ていきたいと思います。

変数への代入

変数への代入は、イコール(=)の前後には空白はNG。もし、スペース等を代入するときはクォーテーションで囲う必要がある。

中括弧({})

コマンドをグルーピングするときは、最後のセミコロン(;)を忘れないように

{ コマンド1; コマンド2; ....;}
鉤括弧([])

「〜でない」を意味するビックリマーク(!)をつける場合には、必ず最初の括弧([)の後に持ってくる。途中にビックリマーク(!)を持ってくると文字列として扱われる。

case文

1つの文の最後を示すセミコロン2つ(;;)を忘れないようにする。セミコロンの間にスペースを入れてはいけない。

複数行にまたぐとき

1行を2行で記述するとき、バックスラッシュ(\)を記載するが、バックスラッシュの後にコメント等を記載するとエラーになるので注意。

testコマンド

testコマンドを括弧([])で記載するときは、括弧のの手前も下記のようにスペースを入れる必要がある。

if [<space>"$NAME" = ""<space>]; then

testコマンドで比較するとき、文字列であればイコール(=)、数字であればeqで比較する。

exprコマンド

exprコマンドも式や値の間にはスペースが必要。exprコマンドを使って変数に格納されているのが数値かどうかを判断できる。下記にサンプルを示す。

if expr "$NUMBER" + 1 > /dev/null 2>&1
if [ $? -lt 2 ]; then
    echo "Numeric"
else
    echo "Not numeric"
fi
readコマンドでファイルを読み込む

readコマンドでファイルの先頭3行を読み込む時には下記のようにする。

exec 3< ファイル
read LINE <&3
read LINE <&3
read LINE <&3

読み込ませるのであれば、下記の方法でもいい。しかし、下記の例で注意しないといけないのは、下記の方法だと、whileがサブシェルで動作するのでwhile内の変数はwhile外では使用できないこと。

while read LINE
do 
    ...
    ...
done < ファイル

もし、while外でもwhile内の変数を利用したければ、下記のようにexecコマンドにリダイレクトしカレントシェルとして動作させる。

exec < ファイル
while read LINE
do 
    ...
    ...
done

***UNIXのファイル名
UNIXのファイル名には、スラッシュ(/)ヌル(\000)以外なら何でもOK

***カラの変数
変数がカラの場合もあるときにはクォーティングを忘れないように。下記の場合、変数がカラだとエラーになってしまう。
>|sh|
NAME=
if [ $NAME = "" ]; then
   echo "NAME is empty."
fi

そこで下記のように$NAME変数をクォーティングする。

NAME=
if [ "$NAME" = "" ]; then
   echo "NAME is empty."
fi
リダイレクション

ファイルにリダイレクトするときは、スペースがあってもなくてもいい。

echo a b c >tmp
echo a b c > tmp

しかし、ディスプリタとかの場合にはスペースなしでないとまずいので、その場合とそろえる意味もあって、上記のスペースなしの方がいい。

終わりに

この第11章は、デバッグの手順と書いてありましたが、基本的にはスクリプトを書くときの注意事項って感じでした。shコマンドでデバッグができますが、あまり突っ込んだことや、サンプルは少ないので、それはこれから自分が使って慣れていくしかなさそうです。

入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界

入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界