I'm new in Bash and I'm stuck with writing a prompt function which asks the user a given questions and accepts the answers yes, no and cancel. I know that there are already a lot of answers to similar questions here on SO but I wasn't able to find an answer that fulfills all my requirements.
Requirements:
The ask function must
- accept a question as parameter: ask "are you happy?"
- accept a answer in [y/n/c]:y,Y,yes,yEs, etc.
- return a value based on the answer: truefor yes,falsefor no- the return value must be assignable to a variable to save it for later: answer=$(ask "...?")
- the return value must be directly useable by ifstatements:if ask "...?" then;
 
- the return value must be assignable to a variable to save it for later: 
- be able to halt the complete execution of the calling script for abort: exit
- ask again if the answer was not yes, no or cancel
- allow a default answer for empty input
- work in scripts that use set -eas well asset +e
I came up with the following solution which doesn't work properly:
ask() {
  while true; do
    read -p "$1 [Y/n/a] " answer
    case $(echo "$answer" | tr "[A-Z]" "[a-z]") in
      y|yes|"" ) echo "true" ; return 0;;
      n|no     ) echo "false"; return 1;;
      a|abort  ) echo "abort"; exit 1;;
    esac
  done
}
# usage1
if ask "Are you happy?" >/dev/null; then
  # ...
fi
# usage2
answer=$(ask "Are you happy?")
For example, the abort does only work when I use -e but then logically the no also causes the script to halt.
 
    