In the process of finding bugs in my Bash scripts, I experimented with "set -e", "set -E" and the "trap" command. In this process, I discovered strange behavior in how it $LINENOis evaluated in the context of functions. Firstly, here is a stripped down version of how I am trying to log errors:
#!/bin/bash
set -E
trap 'echo Failed on line: $LINENO at command: $BASH_COMMAND && exit $?' ERR
Now the behavior is different from where the failure occurs. For example, if I follow the above:
echo "Should fail at: $((LINENO + 1))"
false
I get the following output:
Should fail at: 6
Failed on line: 6 at command: false
Everything is as expected. Line 6 is a line containing a single "false" command. But if I end my unsuccessful command in a function and call it like this:
function failure {
echo "Should fail at $((LINENO + 1))"
false
}
failure
Then I get the following output:
Should fail at 7
Failed on line: 5 at command: false
, $BASH_COMMAND : "false", $LINENO "" . . , $BASH_COMMAND?
, Bash. 3.2.51. , , , 3.2.51.
EDIT: , , . , , .
script:
#!/bin/bash
set -E
function handle_error {
local retval=$?
local line=$1
echo "Failed at $line: $BASH_COMMAND"
exit $retval
}
trap 'handle_error $LINENO' ERR
function fail {
echo "I expect the next line to be the failing line: $((LINENO + 1))"
command_that_fails
}
fail
:
I expect the next line to be the failing line: 14
Failed at 14: command_that_fails
:
I expect the next line to be the failing line: 14
Failed at 12: command_that_fails
12 command_that_fails. 12 function fail {, . ${BASH_LINENO[@]}, 14.