help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

ERR trap, pipeline, and errtrace


From: Boris Kolpackov
Subject: ERR trap, pipeline, and errtrace
Date: Thu, 7 Jan 2021 09:23:35 +0200
User-agent: Mutt/1.5.24 (2015-08-30)

I would like to confirm that the following behavior is expected and
not a bug that could be eventually fixed (thus breaking our scripts):

--------------------------------------------------------------------
#! /usr/bin/env bash

function error_trap ()
{
  echo trap 1>&2
  exit 1
}

trap error_trap ERR
set -o errtrace

function fail ()
{
  echo good 1>&2
  false
  echo bad 1>&2
}

fail | cat

if [ "${PIPESTATUS[0]}" -ne 0 ]; then
  echo failed 1>&2
fi
--------------------------------------------------------------------

This script prints the following (tested with bash versions 4.3, 4.4,
and 5.0):

good
trap
failed

Is this behavior expected ? As you might have recognized, this is a
workaround for the infamous "set -e; if myfunc ..." issue[1].

The two relevant pieces of the documentation are the trap builtin and
errtrace (-E) (quoting only the relevant parts):

"
trap

  The ERR trap is not executed if the failed command is part of the 
  command list immediately following an until or while keyword, part 
  of the test following the if or elif reserved words, part of a 
  command executed in a && or || list except the command following 
  the final && or ||, any command in a pipeline but the last, or if 
  the command’s return status is being inverted using !. These are
  the same conditions obeyed by the errexit (-e) option.
"

"
-E

  If set, any trap on ERR is inherited by shell functions, command
  substitutions, and commands executed in a subshell environment. 
  The ERR trap is normally not inherited in such cases.
"

In a way this behavior does make sense since I believe a pipeline is
considered a subshell. If it is indeed the expected behavior, perhaps,
this part of the trap documentation

"...any command in a pipeline but the last..."

Could be clarified along these lines:

"... any command in a pipeline but the last unless the errtrace (-E) option
 is specified ..."


[1] https://mywiki.wooledge.org/BashPitfalls#errexit



reply via email to

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