夏の午後の熱を迂回するためにbashで遊んでいました。突然私はそれが原因であると判断できない不思議な結果を得ました。bash trapの神秘的なLINENO ERV
少し説明しましょう。
私はトラップERRを使用して、bashスクリプトのデバッグ機能をいくつか作成しています。
この
は正常に動作するスクリプトです:traperror() {
local err=$? # error status
local line=$1 # LINENO
[ "$2" != "" ] && local funcstack=$2 # funcname
[ "$3" != "" ] && local linecallfunc=$3 # line where func was called
echo "<---"
echo "ERROR: line $line - command exited with status: $err"
if [ "$funcstack" != "" ]; then
echo -n " ... Error at function ${funcstack[0]}() "
if [ "$linecallfunc" != "" ]; then
echo -n "called at line $3"
fi
echo
fi
echo "--->"
}
#trap 'traperror $LINENO ${FUNCNAME}' ERR
somefunction() {
trap 'traperror $LINENO ${FUNCNAME} $BASH_LINENO' ERR
asdfas
}
somefunction
echo foo
出力する(標準エラー出力は、明確にするため/dev/null
に進み、bashのエラーは、あなたが知っているようで、もちろんfoo.sh: line 23: asdfas: command not found
のあるエラーコード127)
~$ bash foo.sh 2> /dev/null
<---
ERROR: line 21 - command exited with status: 127
... Error at function somefunction() called at line 24
--->
foo
すべての行番号は右で、21行目は "somefunction"関数を開始し、24行目は呼び出される場所です。
しかし私は最初のトラップ(メインの1)をアンコメント場合、私はこの出力を得る:場合
~$ bash foo.sh 2> /dev/null
<---
ERROR: line 21 - command exited with status: 127
... Error at function somefunction() called at line 24
--->
<---
ERROR: line 15 - command exited with status: 127
--->
foo
私は最初のトラップのコメントを解除し、私はエラーがあることを得る二番目のコメントそれは間違ったコマンドが置かれている絶対行なので、行23にもあります。
~$ bash foo.sh
<---
ERROR: line 23 - command exited with status: 127
--->
foo
私の質問は、なぜ15行目ですか?その行番号はどこから来ますか? 15行目はトラップ関数の最後の行です。誰もが普通の英語で説明することができますなぜtrapは、行21のエラーを生成した行として呼び出す関数の最後の行を返します?
ありがとうございます!誰かがデバッグ機能に興味を持っているだけの場合には
EDIT
。この製品版である:
として動作します# Copyright (c): Hilario J. Montoliu <[email protected]>
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version. See http://www.gnu.org/copyleft/gpl.html for
# the full text of the license.
set -o errtrace
trap 'traperror $? $LINENO $BASH_LINENO "$BASH_COMMAND" $(printf "::%s" ${FUNCNAME[@]})' ERR
traperror() {
local err=$1 # error status
local line=$2 # LINENO
local linecallfunc=$3
local command="$4"
local funcstack="$5"
echo "<---"
echo "ERROR: line $line - command '$command' exited with status: $err"
if [ "$funcstack" != "::" ]; then
echo -n " ... Error at ${funcstack} "
if [ "$linecallfunc" != "" ]; then
echo -n "called at line $linecallfunc"
fi
else
echo -n " ... internal debug info from function ${FUNCNAME} (line $linecallfunc)"
fi
echo
echo "--->"
}
somefunction() {
asdfasdf param1
}
somefunction
echo foo
:
~$ bash foo.sh 2> /dev/null
<---
ERROR: line 26 - command 'asdfasdf param1' exited with status: 127
... Error at ::somefunction::main called at line 29
--->
<---
ERROR: line 22 - command 'asdfasdf param1' exited with status: 127
... internal debug info from function traperror (line 0)
--->
foo
hmontoliu:このコードにライセンスを明示的に割り当てることはできますか?そうすれば、オープンソースのプロジェクトではあなたの明示的な許可を得ることなくそれを使うことができます:-)あなたが確信が持てないなら、http://choosealicense.com/は良いリソースです。私はこのコードのためにGPLまたはLGPLをお勧めしますが、明らかに個人的な好みです – Hamy
私はGPLライセンスを追加しました。ありがとうございます – hmontoliu
ありがとう!私は、これを含むdebianにマージされたコードを取得しようとしています。それが終わったら私はここであなたを更新します(そしてあなたが貢献者として言及されていることを保証することができます) – Hamy