Właśnie bawiłem się bashem, aby ominąć letnie popołudniowe upały, gdy nagle mam tajemniczy wynik, dla którego nie mogę określić jego pochodzenia.Tajemniczy LINENO w pułapce pułapki ERR
Pozwól mi wyjaśnić trochę.
Używam pułapki ERR do tworzenia niektórych funkcji debugowania dla moich skryptów basha.
Jest to skrypt, który działa prawidłowo:
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
Wyjście jest (stderr idzie /dev/null
dla jasności; błąd bash jest oczywiście foo.sh: line 23: asdfas: command not found
która jak wiecie kod błędu 127)
~$ bash foo.sh 2> /dev/null
<---
ERROR: line 21 - command exited with status: 127
... Error at function somefunction() called at line 24
--->
foo
Wszystkie numery linii to z prawej, linia 21 to początek funkcji "somefunction", a linia 24 jest tam, gdzie jest wywoływana.
Jednak jeśli I odkomentuj pierwszą pułapkę (jeden w głównym) otrzymuję ten wynik:
~$ 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
W przypadku I Odkomentuj pierwszą pułapkę i skomentować drugi dostaję, że błąd znajduje się w linii 23, która jest właściwa, ponieważ jest to linia absolutna, w której umieszczone jest niewłaściwe polecenie.
~$ bash foo.sh
<---
ERROR: line 23 - command exited with status: 127
--->
foo
Moje pytanie brzmi: dlaczego linia 15? skąd pochodzi ten numer linii? Linia 15 jest ostatnią linią w funkcji pułapki. Czy ktokolwiek może wyjaśnić prostym językiem, dlaczego pułapka zwraca ostatni wiersz funkcji, którą wywołuje, jako linię, która spowodowała błąd w linii 21?
Z góry dziękuję!
EDIT
Tylko w przypadku, gdy ktoś jest zainteresowany funkcji debugowania. Jest to wersja produkcyjna:
# 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
Który będzie działać jako:
~$ 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: Czy istnieje możliwość przypisania licencji do tego kodu? W ten sposób projekty open-source mogą z niego korzystać bez potrzeby uzyskania wyraźnego pozwolenia :-) Jeśli nie masz pewności, http://choosealicense.com/ to dobry zasób. Polecam GPL lub LGPL dla tego kodu, ale to oczywiście osobiste preferencje. – Hamy
Hamy, dodałem licencję GPL. Dziękuję – hmontoliu
Wielkie dzięki! Pracuję, aby uzyskać fragment kodu połączony z debianem, który zawiera to. Jeśli to przejdzie, uaktualnię cię tutaj (i możemy zapewnić, że jesteś wymieniony jako contrib) – Hamy