Bash関数呼び出しスタックトレースに取り組んでいます...
スクリプトはエラーをトラップし、callStack()
関数を実行します。ただし、トラップすると、トラップが発生した関数ではなく、callStack()
関数自体の呼び出しスタックが常に表示されます...
_/share/sbin/zimdialog: line 647: status: command not found
Function call stack ( command.function() ) ...
/share/sbin/zimdialog.main()
/share/sbin/include.callStack()
_
errantFunction()
のようなものを含むスタックトレースを取得しようとしています...
_/share/sbin/zimdialog: line 647: status: command not found
Function call stack ( command.function() ) ...
/share/sbin/zimdialog.main()
/share/sbin/zimdialog.errantFunction()
/share/sbin/include.callStack()
_
トラップは次のようにコード化されます...
_trap callStack HUP INT QUIT TERM ERR
_
callStack()
関数は次のようにコード化されます...
_function callStack () {
{ isNotNull "$1" && isHelp "$1"; } && {
helpShow 'callStack
Diagnostics regarding where the call to this function came from'
return
}
local T="${T} "
local STACK=
i=${#FUNCNAME[@]}
((--i))
printf "${T}Function call stack ( command.function() ) ...\n" >&2
T="${T} "
while (( $i >= 0 ))
do
STACK+="${T}${BASH_SOURCE[$i]}.${FUNCNAME[$i]}()\n"
T="${T} "
((--i))
done
printf "$STACK" >&2
}
_
補足:-Eなどが機能しないように設定
_/share/sbin/gshlib
_ ..で.
_set -e
set -E
set -T
shopt -s extdebug
trap $(callStack) ERR
function initialize () {
:
logstatus #<<< ERROR FOR TESTING trap
}
export -f initialize
_
/share/sbin/gshlib.initialize()
内でlogStatus
をlogstatus
に誤って名前を付けて、_trap ERR
_を起動すると、私が得られる最善の方法は...
_ Function call stack ...
| /share/sbin/archive.main()
| /share/sbin/include.include()
| /share/sbin/gshlib.source()
| /share/sbin/include.callStack()
/share/sbin/gshlib: line 109: logstatus: command not found
_
私が手に入れたいのは...
_ Function call stack ...
| /share/sbin/archive.main()
| /share/sbin/include.include()
| /share/sbin/gshlib.source()
| /share/sbin/gshlib.initialize()
| /share/sbin/include.callStack()
/share/sbin/gshlib: line 109: logstatus: command not found
_
必要がある set -E
(またはset -o errtrace
)そのためtrap ERR
は呼び出された関数に継承されます。
これを行うと、呼び出しスタック内の各関数がスクリプトエラーによって(ゼロ以外の終了コードで)終了するため、カスケードエラーレポートが表示される可能性があります。
ERR
は、失敗が致命的とは見なされないコンテキスト(if
やwhile
など)でのシェル関数の呼び出しによってトリガーされません。このような状況では、スタックトレースはおそらく表示されませんが、バージョン固有であるかどうかはわかりません。