help-bash
[Top][All Lists]
Advanced

[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"



reply via email to

[Prev in Thread] Current Thread [Next in Thread]