Bashシェルスクリプトで関数のコールスタックを取得・出力する
Contents
はじめに
Bashシェルスクリプトでログを出力する際などに以下のような情報が欲しい場合がありました。
- 「現在実行中の関数」の名前
- 「現在実行中の関数」の呼び出し元
これらの情報を取得する方法を説明します。
検証環境
$ uname -moi
x86_64 x86_64 GNU/Linux
$ bash -version | head -n 1
GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
$FUNCNAME
変数を使って「コールスタック」を参照する
$FUNCNAME
という配列の変数を参照することで、関数の「コールスタック」情報が取得できます。
サンプルスクリプトを通して、使い方を見ていきましょう。
サンプルスクリプトで確認してみる
以下のような2つのスクリプトを作成して動作を確認してみます。
$ ls
script_main.sh script_sub.sh
$ cat script_main.sh
#!/usr/bin/env bash
./script_sub.sh
echo
. ./script_sub.sh
$ cat script_sub.sh
#!/usr/bin/env bash
f1 () {
declare -p FUNCNAME
echo "${FUNCNAME[@]}"
echo "0 = ${FUNCNAME[0]}"
echo "1 = ${FUNCNAME[1]}"
echo "2 = ${FUNCNAME[2]}"
echo "3 = ${FUNCNAME[3]}"
}
f2 () {
f1
}
f2
f1
関数を呼び出すまでの流れは大きく以下のようになっています。
ただし、script_main.sh
から script_sub.sh
を呼び出す方法として2つの方法を実行しています。
実行結果は以下のようになります。
$ ./script_main.sh
declare -a FUNCNAME='([0]="f1" [1]="f2" [2]="main")'
f1 f2 main
0 = f1
1 = f2
2 = main
3 =
declare -a FUNCNAME='([0]="f1" [1]="f2" [2]="source" [3]="main")'
f1 f2 source main
0 = f1
1 = f2
2 = source
3 = main
$FUNCNAME
変数について
サンプルプログラムからわかったことを整理します。
declare -p FUNCNAME
コマンドから、変数$FUNCNAME
は配列であることがわかる。${FUNCNAME[@]}
でコールスタックがすべて取得できる${FUNCNAME[0]}
で現在実行中の関数名(ここではf1
)が取得できる${FUNCNAME[1]}
で呼び出し元の関数名(ここではf2
)が取得できる${FUNCNAME[N]}
( N は添字の最終値)は呼び出し元のmain
という関数名(?)が取得できる.
あるいはsource
コマンド経由でスクリプトを読み込んだ場合は、source
という中間関数がコールスタックに積まれる
ひとこと
実行中の関数名をログ出力させたい場合などには、以下のような命令が使えます。
$ echo "${FUNCNAME[0]} start" 2>&1
ディスカッション
コメント一覧
まだ、コメントがありません