Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Differences between "TRAPERR()" and "trap foo ERR"

On Tue, Jul 27, 2021 at 8:47 PM Zach Riggle <zachriggle@xxxxxxxxx> wrote:
> Overall, there are two observations.
> 1. The behavior that TRAPNAL will receive NAL as its first argument,
> where NAL corresponds to a the system-defined signal values (e.g.
> SIGSEGV == 11).  The name for this signal can be gotten from
> ${signals[x+1]}.  This should be documented.

9.3.2 Trap Functions:

     If defined and non-null, this function will be executed whenever
     the shell catches a signal SIGNAL, where NAL is a signal name as
     specified for the kill builtin.  The signal number will be passed
     as the first parameter to the function.

> 2. This behavior does not expand to "trap func NAL" statements, even
> if we try to pass "$@" to some function.  This seems like a bug.

It's not a bug; it's the normal behavior of the "trap" in the shell
language.  The TRAPnal form and the argument it receives are a zsh

The "trap" builtin takes an arbitrary list of commands rather than a
function body.  There is therefore no "argument list" where the signal
number can be passed.  If you write

  trap 'echo in a trap' USR2

you will see that there is no TRAPUSR2 function created.  "unfunction
TRAPUSR2" removes the USR2 trap as a side-effect, but also complains
"no such hash table element".  That's a bit of an oddity, but is in
part why the doc for the "trap" builtin says:

     Defining a trap under either name causes any trap under an
     alternative name to be removed.  However, it is recommended that
     for consistency users stick exclusively to one name or another.

Other distinctions considered important are also mentioned there:

     Note that traps defined with the trap builtin are slightly
     different from those defined as 'TRAPNAL () { ...  }', as the
     latter have their own function environment (line numbers, local
     variables, etc.)  while the former use the environment of the
     command in which they were called.  For example,

          trap 'print $LINENO' DEBUG

     will print the line number of a command executed after it has run,

          TRAPDEBUG() { print $LINENO; }

     will always print the number zero.

You might also read about the POSIX_TRAPS and LOCAL_TRAPS setopts.

Messages sorted by: Reverse Date, Date, Thread, Author