導入
書いたスクリプトが思ったとおりに動かない。エラーメッセージも出ない。そんなときに闇雲に書き換えても解決しません。どこまで進んだか・変数に何が入っているかを見る方法を知っておきましょう。
説明
いちばん強力なのが set -x です。実行した行が、展開後の姿で表示されます。
#!/bin/bash
TARGET=logs
set -x
echo "対象は $TARGET"
result=$(ls "$TARGET" | wc -l)
set +x
echo "ファイル数: $result(ここはトレースされません)"
set -x から set +x までの間だけ、+ echo "対象は logs" のように、変数が展開されたあとの実際のコマンドが表示されます。- が有効化、+ が無効化です。
スクリプト全体を追いたいときは、実行時に指定することもできます。
sh -x script.sh
デバッグの手順は、だいたいこの順番です。
flowchart TD
A["動かない"] --> B["set -x で実行された行を見る"]
B --> C{"変数の中身は想定どおり?"}
C -->|"違う"| D["echo で値を確認<br/>クォートを疑う"]
C -->|"合っている"| E["終了ステータス $? を確認"]
E --> F["エラーメッセージを 2>&1 で拾う"]
もう1つの基本が、原始的ですが確実な echo デバッグ です。
echo "デバッグ: TARGET=[$TARGET]" >&2
値を [ ] で囲むのがコツです。空文字なのか、スペースが入っているのかが目で見て分かります。>&2 を付けておけば、本来の出力を汚しません。
保存したスクリプトの文法をチェックしてくれる ShellCheck というツールもあります(本コースのシミュレータには入っていません)。クォート漏れや未定義変数を指摘してくれるので、実際に書き始めたら導入する価値があります。
やってみよう
スクリプトを実行して、set -x 区間だけ + … のトレースが出ることを確かめましょう。次に端末で sh -x script.sh と実行し、全行にトレースが付くことを見てください。他人のスクリプトを読み解くときの強い味方になります。
演習
sh -x script.sh を実行して、トレース付きで動かしてください(+ echo "対象は logs" のような行が出ます)。
ヒント1を見る
実行時にオプションを付けます: sh -x ファイル名
ヒント2を見る
下の端末で sh -x script.sh