[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: errortracing inside || and eval
From: |
Tycho Kirchner |
Subject: |
Re: errortracing inside || and eval |
Date: |
Thu, 1 Dec 2022 11:11:38 +0100 |
Am 30.11.22 um 17:18 schrieb Chet Ramey:
On 11/30/22 8:56 AM, Tycho Kirchner wrote:
Hi!
We would like to run an error trap inside a function, even if it is called within
|| -> func || true.
While bash's manpage documents in the trap-section that no error trap runs
"if the failed command ... is part of a command executed in ||", we found the following
workaround, using "eval":
This is a bug in eval.
Dear Chet Ramey,
thanks for the quick response. So, we cannot rely on "eval" here. However, we
think that such an behavior is desirable.
To be more precise, we have a user executing a bash-function of a large bioinformatics pipeline, which heavily relies on "set -o
errtrace". However, the user has no knowledge about this implementation detail and calls the function like "biofunc ||
exit", thus destroying the pipeline's error handling. We would kindly ask to introduce a "set -o errtrace_force"
parameter, allowing to officially enable error tracing even if running inside ||. Each ||, &&, "if !", etc., would
constitute the "catch" clause.
Our current "eval hack" already allows stack-unwinding similar to exceptions in
other programming languages. Please preserve the possibility for such an behavior.
Thanks and kind regards
Tycho and Konstantin
___________________________________
$ ./test.sh
RUNNING HOOK
fun start arg_fun
TRACE: inner fun main
inner start arg_inner
running error trap 34
running error trap 50
EXIT with 42
___________________________________
#!/usr/bin/env bash
set -o errtrace
set -o functrace
shopt -s expand_aliases
TRAP_STRING='__ret=$?; echo running error trap $LINENO >&2; [[ -n "${FUNCNAME+x}" ]]
&& return $__ret; exit $__ret'
trap "$TRAP_STRING" ERR
err_hack_2=(
"echo foobar;"
)
alias err_hack='local errtrap="$(trap -p ERR)"
trap "___errtrap_ok=true" ERR
false
source <(printf "%s\n" "$errtrap")
if [ -z "${___errtrap_ok+x}" ]; then
echo "RUNNING HOOK" >&2
# declare -f "${FUNCNAME[0]}" >&2
# to not pollute our stack, instead of calling "${FUNCNAME[0]}", eval it
instead.
# This also solves the alias argument passing problem.
eval "set -o errtrace; trap \"\$TRAP_STRING\" ERR ; $(declare -f "${FUNCNAME[0]}" | awk
"NR > 2" | head -n -1 )"
return $?
fi
unset ___errtrap_ok'
function inner(){
err_hack
echo "TRACE: ${FUNCNAME[@]}"
echo inner start "$1"
(exit 42)
echo inner end
}
function fun(){
err_hack
echo fun start "$1"
inner arg_inner
echo fun end
}
ret=0
fun arg_fun || ret=$?
echo "EXIT with $ret"
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: errortracing inside || and eval,
Tycho Kirchner <=