Bash: Err trap not reset

From FVue
Jump to: navigation, search

Problem

I have a script which is sourced (included) in the current shell. The script doesn't reset the ERR trap to the value it had when the shell was started.

Script to reproduce the problem:

#!/bin/bash
#--- foo.sh ------------------------------------------------------------
# Example program to reproduce problem of `ERR trap not reset'
# See: http://fvue.nl/wiki/Bash:_Err_trap_not_reset

function foo_init   { echo foo_init 
                      trap 'echo trapped' ERR;} # Set ERR trap 

function foo_deinit { echo foo_deinit
                      trap - ERR             ;} # Reset ERR trap

foo_init
false # Trigger ERR trap
foo_deinit

Example run:

$> trap                     # No output, so no traps defined
$> . foo.sh
foo_init
trapped                     # `false' has triggered the ERR trap
foo_deinit                  # This should've reset the ERR trap
$> trap
trap -- 'echo trapped' ERR  # Surprise, the ERR trap is not reset
$>

Environment

GNU bash, version 3.00.16(1)-release (i586-suse-linux)
Copyright (C) 2004 Free Software Foundation, Inc.

Solution

From `info bash':

The `trap' builtin (*note Bourne Shell Builtins::) allows an `ERR'
pseudo-signal specification, similar to `EXIT' and `DEBUG'.
Commands specified with an `ERR' trap are executed after a simple
command fails, with a few exceptions.  The `ERR' trap is not
inherited by shell functions unless the `-o errtrace' option to
the `set' builtin is enabled.

With set -o errtrace, the script now becomes:

#!/bin/bash
#--- foo.sh ------------------------------------------------------------
# Example program to reproduce problem of `ERR trap not reset'
# See: http://fvue.nl/wiki/Bash:_Err_trap_not_reset

function foo_init   { echo foo_init 
                      trap 'echo trapped' ERR;} # Set ERR trap 

function foo_deinit { echo foo_deinit
                      trap - ERR             ;} # Reset ERR trap

set -o errtrace   # on
foo_init
false             # Trigger ERR trap
foo_deinit
set -o errtrace   # off

Example run:

$> trap                     # No output, so no traps defined
$> . foo.sh
foo_init
trapped                     # `false' has triggered the ERR trap
foo_deinit                  # This should reset the ERR trap
$> trap                     # No output, so the trap is reset
$>

See also

Bash: Catch error
Skeleton bash script to catch errors in either executed or sourced scripts
Bash: Trap
Investigating bash-trap behaviour

Journal

20061209

#!/bin/bash
#--- foo.sh ------------------------------------------------------------
# Example program to reproduce problem of `ERR trap not reset'
# See: http://fvue.nl/wiki/Bash:_Err_trap_not_reset

function foo_init   { echo foo_init 
                      trap 'echo trapped' ERR;} # Set ERR trap 

function foo_deinit { echo foo_deinit
                      trap - ERR             ;} # Reset ERR trap

function foo_test   { false                  ;} # Trigger ERR trap

set -o errtrace  # on
foo_init
foo_test
foo_deinit
set +o errtrace  # off

Example run of the above script:

$> trap
$> . foo.sh
foo_init
trapped       # Q: Why is the ERR trap triggered twice?
trapped       # A: Because of `errtrace' it is triggered first  
foo_deinit    #    within `foo_test()', second in the main
$> trap       #    script, because `foo_test()' returns false
$>

Comments

blog comments powered by Disqus