[Top][All Lists]

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

Re: Second trap invocation is ignored?

From: Eduardo A . Bustamante López
Subject: Re: Second trap invocation is ignored?
Date: Mon, 6 Apr 2015 10:31:49 -0500
User-agent: Mutt/1.5.23 (2014-03-12)

After reading the manual, it is indeed undocumented that DEBUG, RETURN and ERR
have the same semantics for `source' and function calls. Or perhaps it's
documented, but I didn't take the time to read it all.

There information related to DEBUG is scattered across man bash. Some of the
relevant stuff:

>From `FUNCTIONS', second paragraph:

       All other aspects of the shell execution environment are identical 
between a function  and  its
       caller  with  these  exceptions:  the  DEBUG  and RETURN traps (see the 
description of the trap
       builtin under SHELL BUILTIN COMMANDS below) are not inherited  unless  
the  function  has  been
       given  the  trace  attribute (see the description of the declare builtin 
below) or the -o func‐
       trace shell option has been enabled with the set builtin (in which case 
all  functions  inherit
       the  DEBUG  and  RETURN  traps), and the ERR trap is not inherited 
unless the -o errtrace shell
       option has been enabled.

>From the description of the `set' builtin (same as functrace):

              -T      If set, any traps on DEBUG and RETURN are inherited by 
shell functions,  command
                      substitutions,  and  commands executed in a subshell 
environment.  The DEBUG and

>From the description of the `trap' builtin:

              If  a  sigspec  is  EXIT  (0)  the command arg is executed on 
exit from the shell.  If a
              sigspec is DEBUG, the command arg is executed before every simple 
command, for  command,
              case command, select command, every arithmetic for command, and 
before the first command
              executes in a shell function (see SHELL GRAMMAR above).  Refer to 
the description of the
              extdebug  option to the shopt builtin for details of its effect 
on the DEBUG trap.  If a
              sigspec is RETURN, the command arg is executed each time a shell 
function  or  a  script
              executed with the . or source builtins finishes executing.

That's all the documentation I could find regarding this. Now, what really 


address@hidden ~ % bash -c 'trap "echo bar" DEBUG; source /dev/fd/0; :' <<< 
'trap "echo foo" DEBUG; :' 

Here, the first `bar' is executed before `source'. Then, we enter a new
`scope', or whatever this is called. Then, there's `foo', due to the `:' called
inside the sourced script. After we `return' from the sourced script, `bar' is
written, before the `:' from the main script (the -c one).

So, essentially, we have two DEBUG traps set at the same time, living in
different scopes. (DEBUG, RETURN and ERR are the only ones special here, I


address@hidden ~ % bash -Tc 'trap "echo bar" DEBUG; source /dev/fd/0; :' <<< 
'trap "echo foo" DEBUG; :'

Now, here we're using -T, so we essentially removed that `scoping' thing, or
whatever, making DEBUG a single global trap. The output is due to:

bar: before `source'
bar: before `trap' inside the sourced script
foo: before `:' inside the sourced script
foo: before `:' inside the main script (-c)

So, from what you can see, there's a pretty convincing and consistent
explanation of what bash is doing. Now, is this documented properly? I do not
think so.

IMO, we should include a paragraph in the description of the `source' builtin
that it behaves similarly to functions in terms of traps. (IIRC, `return'
already documents this similarity). We should also update the description of
the set -T option (and perhaps explain the similarity in the FUNCTIONS section).

I'll prepare a patch to the documentation later if I have the time :-)

Eduardo Bustamante

reply via email to

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