diff --git a/Src/exec.c b/Src/exec.c index e955e85df..916a3567d 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -1485,7 +1485,9 @@ execlist(Estate state, int dont_change_job, int exiting) next = state->pc + WC_SUBLIST_SKIP(code); /* suppress errexit for commands before && and || and after ! */ if (isandor || isnot) - noerrexit |= NOERREXIT_EXIT | NOERREXIT_RETURN; + noerrexit = oldnoerrexit | NOERREXIT_EXIT | NOERREXIT_RETURN; + else + noerrexit = oldnoerrexit; switch (WC_SUBLIST_TYPE(code)) { case WC_SUBLIST_END: /* End of sublist; just execute, ignoring status. */ diff --git a/Test/C03traps.ztst b/Test/C03traps.ztst index de57765a0..9fefdf713 100644 --- a/Test/C03traps.ztst +++ b/Test/C03traps.ztst @@ -995,6 +995,25 @@ F:Must be tested with a top-level script rather than source or function ?loop 0 ?loop 1 + ( set -e; true && {false; echo NOT REACHED} ) + ( trap "print Trapped!" ERR; true && {false} ) + ( trap "print Trapped!" ERR; true && if true; then false; fi ) + ( trap "print Trapped!" ERR; true && {false} always {true} ) + ( true && (set -e; false; echo NOT REACHED) ) + ( true && (trap "print Trapped!" ERR; false) ) + ( true && { set -e; false; echo NOT REACHED } ) + ( true && { trap "print Trapped!" ERR; false } ) + ( set -e; true && (false; echo one) || echo two ) + ( set -e; true && { false; echo one; } || echo two ) +0:ERR_EXIT is triggered by last command in an AND-OR list +>Trapped! +>Trapped! +>Trapped! +>Trapped! +>Trapped! +>one +>one + if zmodload zsh/system 2>/dev/null; then ( trap 'echo TERM; exit 2' TERM