bash でスタックトレース
bash には perl の confess 相当のサブルーチンがありません。しかし実装することができます。
#!bash source carp.sh foo() { confess "something wrong" echo "this line will not be executed." } bar() { foo } baz() { bar } baz exit
$ sh stacktrace.sh something wrong at stacktrace.sh line 5 foo() called at stacktrace.sh line 9 bar() called at stacktrace.sh line 12 baz() called at stacktrace.sh line 15 $
carp.sh の中身はこちら。
#!bash confess() { local mess max i line src mess=$1 let max=${#BASH_LINENO[@]}-1 line=${BASH_LINENO[0]} src=${BASH_SOURCE[1]} echo "$mess at $src line $line" >&2 i=1 while [ $i -lt $max ]; do line=${BASH_LINENO[$i]} src=${BASH_SOURCE[`expr $i + 1`]} echo " ${FUNCNAME[$i]}() called" \ "at $src line $line" >&2 let i=$i+1 done exit 255 }
BASH_SOURCE と FUNCNAME の要素番号が1個ずれていることに気づかず、間違ったコードを乗せていた。訂正済み。