I'm writing a Bash script in which I issue the "set -E" command, and use traps to detect errors. The "set -E" command causes the ERR trap to be inherited by shell functions. This is a must for me since I'm also using OpenSSL commands which trigger traps that are undetectable by the shell by default.
All this was working fine, until I decided to ask the user a question, and return a value from a function indicating the answer: 0 for yes, 1 for no. When I return 1 from the function, the shell detects that as an ERR trap and executes the trap function. I don't want that to happen.
The code below is a bare-bones example. When I answer "no" (function returns 1), the ERR trap function gets executed and displays "Test.sh: error 1 occurred on line 37".
When I comment out the "set -E" command, this problem goes away, but then the shell can't detect OpenSSL command failures.
How can I return 1 from the function without this problem occurring? Thanks.
#!/bin/bash
ScriptName=$(basename "$0")
#set -E # causes ERR trap to be inherited by shell functions
trap 'SigintHandler' SIGINT
trap 'ErrHandler $? $LINENO' ERR
function main() {
Confirm "OK to delete?"
}
function Confirm() {
question="$1"
while true; do
read -p "$question [y/n]: " yn
case $yn in
[Yy]*) return 0;;
[Nn]*) return 1;;
esac
done
}
function SigintHandler() {
printf "%s: aborted by user\n" "$ScriptName"
exit 1
}
function ErrHandler() {
errNum="$1"
lineNum="$2"
printf "%s: error %s occurred on line %s\n" "$ScriptName" "$errNum" "$lineNum"
exit 1
}
main "$@"
The ERR
trap is executed whenever a command or function returns a non-zero exit status, since that's how errors are indicated to the shell.
However, it's not executed when the command is used as a condition in if
, while
, or until
, or part of an &&
or ||
list. So you need to test the result of the call to Confirm
, e.g.
function main() {
if Confirm "OK to delete?"
then
rm -- "$@"
fi
}