[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Bugs in ERR and RETURN traps
From: |
Paul Donohue |
Subject: |
Bugs in ERR and RETURN traps |
Date: |
Thu, 19 Feb 2015 14:54:55 -0500 |
I posted bug reports at https://savannah.gnu.org/support/index.php?108738 and
https://savannah.gnu.org/support/index.php?108749 but there seems to be very
little activity (or none at all?) on the issue tracker, so I figured it might
be a good idea to post to the mailing list too.
I'm using bash 4.3.30(1) in Ubuntu, and have run across two odd behaviors in
ERR and RETURN traps that I think are bugs.
First:
When an ERR trap is called, ${BASH_SOURCE[0]}, ${FUNCNAME[0]}, and $LINENO
normally indicate the file/function/line which called the command that returned
a non-zero status. This is good.
However, if an ERR trap is called because a function returned a non-zero
status, then ${BASH_SOURCE[0]} and ${FUNCNAME[0]} still indicate the
file/function which called the function that returned a non-zero status, but
$LINENO indicates the line number of the last command in the function that was
called, and the line number of the call to the function is not available. This
doesn't really make sense.
Example:
$ cat <<'END' >script1
test_fun() {
return 1
}
END
$ cat <<'END' >script2
#!/bin/bash
# Some blank lines to adjust the line numbers relative to script1
source script1
trap 'echo error at: ${BASH_SOURCE[0]} ${FUNCNAME[0]} $LINENO
${BASH_LINENO[@]}' ERR
false # Trigger the ERR trap with a command on line 6
test_fun # Trigger the ERR trap with a function on line 7
END
$ chmod 755 script2
$ ./script2
error at: ./script2 main 6 0
error at: ./script2 main 2 0
$
This seems like a bug. I would expect one of two behaviors here:
1) In the ERR trap on function return, $LINENO should point to the line which
called the function (just as ${BASH_SOURCE[0]} and ${FUNCNAME[0]} point to the
file/function which called the function that returned a non-zero status).
2) In the ERR trap on function return, ${BASH_SOURCE[0]}, ${FUNCNAME[0]}, and
$LINENO should point to the last command executed within the function, and
${BASH_SOURCE[1]} ${FUNCNAME[1]} ${BASH_LINENO[0]} should point to the caller
of the function.
Second:
The RETURN trap does not see the exit status of 'return', but rather the exit
status of the last command before 'return' was called.
Example:
$ test_fun()
{
trap 'echo returned $?' RETURN
false # exit status is 1
return 2
}
$ test_fun
returned 1
$
I intuitively expected the above to print 2 instead of 1.
The bash man page states "Any command associated with the RETURN trap is
executed before execution resumes after the function or script." This is a bit
vague, but it seems to imply that the RETURN trap should run after the `return`
command is complete (since the `return` command is part of the function and the
RETURN trap runs "after the function"), which would imply that $? should be set
to the exit status of the return command in the RETURN trap. So, the
documentation seems to back up my intuition here...
The problem I was actually trying to solve was to write a trap that ran only if
the function returned an error. An ERR trap would have been run if any command
within the function returned an error, which was not what I wanted. So, I
simply wrote a RETURN trap which checked $?, but $? did not give me the return
status of the function, so this didn't work.
Thoughts on these? Is there a reason for the current behavior?
Thanks!
- Bugs in ERR and RETURN traps,
Paul Donohue <=