ksaitoの日記

日々試したことの覚え書き

bashのデバッグ

bashは、構文チェック、デバッグメッセージが使えることは知っていましたが、デバッガが使えるとは知りませんでした。

構文チェック

シェルの構文チェックは、-nオプションが使えます。
デバッグを始める前に、シェルの文法チェックをすることができます。

$ cat test.sh
#! /bin/bash

for i in $(seq 1 10)
    echo $i
done
$ bash -n test.sh
test.sh: 行 4: 予期しないトークン `echo' 周辺に構文エラーがあります
test.sh: 行 4: `    echo $i'
$ 

トレースメッセージ

bashの-xオプションを使ってWindowsのバッチファイルのように実行している行を表示することができます。

$ cat test.sh
#! /bin/bash

for i in $(seq 1 3)
do
    echo $i
done
$ bash -x test.sh
++ seq 1 3
+ for i in '$(seq 1 3)'
+ echo 1
1
+ for i in '$(seq 1 3)'
+ echo 2
2
+ for i in '$(seq 1 3)'
+ echo 3
3
$ 

特定の範囲だけトレースしたい場合には、set -xとset+xを使います。

$ cat test.sh
#! /bin/bash

echo start
set -x
echo $i
set +x
for i in $(seq 1 3)
do
    echo $i
done
$ ./test.sh
start
+ echo

+ set +x
1
2
3
$ 

デバッガ

シェルをデバッグするのは、echoが主役と思っていましたが...
bashdbを使って高級言語のデバッガのようにデバッグできます。(知らなかった!)
導入は、以下のとおりです。

$ sudo apt-get install bashdb

起動は、こんな感じです。

$ cat sample.sh 
#! /bin/sh

echo start
for i in $(seq 1 3)
do
    echo $i
done
echo fin

$ bashdb sample.sh 
bash Shell Debugger, release 4.0-0.4

Copyright 2002, 2003, 2004, 2006, 2007, 2008, 2009 Rocky Bernstein
This is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.

(~/work/sample.sh:3):
3:	echo start
bashdb<0> 

listコマンドでソースを表示してstepコマンドで行単位に実行します。

bashdb<0> list
  3:==>echo start
  4:   for i in $(seq 1 3)
  5:   do
  6:       echo $i
  7:   done
  8:   echo fin
  9:   
bashdb<1> step
start
(~/work/sample.sh:4):
4:	for i in $(seq 1 3)
bashdb<2> step
(~/work/sample.sh:6):
6:	    echo $i
bashdb<3> x $i
1
bashdb<4> 

bコマンドでブレークポイントを設定して、cコマンドで継続実行します。

bashdb<5> b 8
Breakpoint 1 set in file ~/work/sample.sh, line 8.
bashdb<6> list
  6:==>    echo $i
  7:   done
  8:   echo fin
  9:   
bashdb<7> c
1
2
3
Breakpoint 1 hit (1 times).
(~/work/sample.sh:8):
8:	echo fin
bashdb<8> 

qコマンドで終了です。

bashdb<8> q
$ 

なかなか使えそうです。

おまけ

bashに--debuggerオプションをつけて起動する方法もあります。
また、シェルの中身がfor文などのbash組み込みの構文だとソースの表示がうまくいかないようです。
echo文をひとつ入れると正しくソースを表示します。

$ bash --debugger ./sample.sh 
Bourne-Again Shell Debugger, release 4.0-0.4

Copyright 2002, 2003, 2004, 2006, 2007, 2008, 2009 Rocky Bernstein
This is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.

(~/work/sample.sh:6):
6:	done
bashdb<(0)> list
  6:==>done
bashdb<(1)> list 1
  1:   #! /bin/sh
  2:   
  3:   for i in $(seq 1 3)
  4:   do
  5:       echo $i
  6:==>done
bashdb<(2)> next
(~/work/sample.sh:3):
3:	
bashdb<3> list
  3:==>
  4:   
  5:   
  6:   
bashdb<4>