Without installing anything on a barebones bash, is there a simple and clear way to:
- test a value
- print out a message if it's not what you want
- still fail (without exiting the window/shell)
Currently, I've got:
[[ -n "$some_val" && -n "$other_val"]] || {echo "Unable to retrieve xxx from yyy"; false}
that's kind of a wtf to read, but then this is more verbose than I'd like for such a simple assertion:
if test -n "$some_val" && test -n "$other_val"; then
echo "Unable to retrieve xxx from yyy"
false
fi
What I'd really love would be to have something like:
test -n "$some_val" -m "some_val missing" && test -n "$other_val" "other_val missing"
or:
[[ -n "$some_val" && -n "$other_val" ]] || fail "Unable to retrieve xxx from yyy"
CodePudding user response:
die() { rc=$?; (( $# )) && printf '%s\n' "$*" >&2; exit $(( rc == 0 ? 1 : rc )); }
do_something || die "explanation of how it failed"
Let's break this down:
- Capturing
$?
at the top of the function lets us get the exit status that caused the function to be invoked. - Checking
$#
lets us log an error message only if there actually was an error to log. - If we do log a message, we send it to stderr so our message doesn't get mixed in with output (and potentially directed to a file or pipeline where the user will never see it).
$(( rc == 0 ? 1 : rc ))
causes us to exit with status 1 ifdie
was called when$?
didn't reflect a failure, or the prior exit status otherwise.
If you don't want to exit the shell interpreter but just want to pass the exit status along, change the exit
to return
.
CodePudding user response:
The function you want is trivial to define:
fail () {
printf '%s\n' "$1" >&2
return "${2:-1}"
}
test -n "$some_val" || fail "Value is empty"
(The definition is overly general, so that you can provide an explicit exit status for the function if 1
isn't desired, for example, complicated_test || fail "Failed, preserving exit status" $?
. The $?
will contain the exit status of the command that allowed the second half of the ||
list to execute.)