diff --git a/bin/miaou-bash b/bin/miaou-bash index 419a029..cb767bb 100755 --- a/bin/miaou-bash +++ b/bin/miaou-bash @@ -28,6 +28,21 @@ function exit { builtin exit "$code" } +function on_usr1 { + last_error=$(tail -n1 "$MIAOU_BASH_ERROR") + cleanup + regex='subshell term: ([0-9]*)' + if [[ "$last_error" =~ $regex ]]; then + code="${BASH_REMATCH[1]}" + debug "on_usr1 code=${code}" + builtin exit "${code}" + else + debug "on_usr1 unknown last error: $last_error" + builtin exit 200 + fi + # >&2 echo "${BASH_SOURCE[2]}: line ${BASH_LINENO[0]}: subshell termination $code from ${FUNCNAME[1]}" +} + function on_return { # regex does not work here unfortunately! if [[ "${BASH_COMMAND}" == 'return '* ]]; then @@ -74,13 +89,19 @@ function on_exit { failure_payload='' if [[ $code -gt 0 ]]; then - - [[ -p /dev/stdout ]] && debug "kill pipe $code !" && >&2 echo "pipe error: original status $code" && kill -SIGPIPE $$ last_error=$(tail -n1 "$MIAOU_BASH_ERROR") last_source=${stack_sources[0]} last_source=${last_source//./"\."} # replace '.' with '\.' regex1="^$last_source: line ([0-9]+): (.*)\$" regex2="^$last_source:([0-9]+) (.*)\$" + + # FIXME: too much tricky + if [[ -p /dev/stdout ]]; then + last_error="subshell term: $code" + >&2 echo "$last_error" + kill -USR1 $$ + fi + # debug "last_error=[$last_error] <=> ${last_source}" if [[ "$last_error" =~ $regex1 || "$last_error" =~ $regex2 ]]; then line=${BASH_REMATCH[1]} @@ -161,10 +182,9 @@ function on_exit { stack_functions[0]="${stack_functions[0]} (hint: prefer source than subshell:3)" fi else - regex='^pipe error:' + regex='^subshell term:' if [[ "$last_error" =~ $regex ]]; then - code=141 - failure_type='PIPE ERROR' + failure_type='SUBSHELL TERM' fi fi fi @@ -215,6 +235,8 @@ function dump_stderr { for i in "${tmp_error[@]}"; do >&4 echo -e "$i" done + else + debug '---no stderr---' fi } @@ -224,7 +246,7 @@ function dump_success { } function cleanup { - trap - ERR TERM EXIT DEBUG + trap - ERR TERM EXIT DEBUG USR1 exec 3>&- 4>&- rm "$MIAOU_BASH_ERROR" } @@ -236,6 +258,7 @@ set -TEue -o pipefail trap 'on_exit $?' ERR TERM INT EXIT trap 'on_return' DEBUG +trap 'on_usr1' USR1 BASH_ARGV0="$1" && shift # to pretend script runs by itself # magic FD + delayed tee => /dev/fd/3 means delayed stderr, /dev/fd/4 remains original stderr diff --git a/test/stub/scenario.bash b/test/stub/scenario.bash index 526218b..e42d942 100755 --- a/test/stub/scenario.bash +++ b/test/stub/scenario.bash @@ -7,11 +7,26 @@ readonly BASEDIR # SCENARII -function do_pipe_error { +function do_subshell_term { + # grep nope nope + echo "found=$(grep nope nope)" +} + +function do_last_false { + # FIXME: provides error detection + ! true +} + +function do_unbound_associative { declare -A associative associative['A']='Abc' + + # this is fine [[ -v associative['A'] ]] && echo "${associative['A']}" - true + [[ -v associative['B'] ]] && echo "${associative['B']}" + + # this fails + echo "${associative['B']}" } function do_false {