Reputation: 751
I need to check if a list of env vars are existing. Now I'm doing this which of course is a very dumb solution:
if [ -z "$MONGOLAB" ]; then
echo "Missing \$MONGOLAB"
exit 1
fi
if [ -z "$APP_PORT" ]; then
echo "Missing \$APP_PORT"
exit 1
fi
if [ -z "$ENV" ]; then
echo "Missing \$ENV"
exit 1
fi
... more checks here
How could I refactor this? :)
Upvotes: 1
Views: 124
Reputation: 30781
Here's one way to do it:
#!/bin/bash
set -e
err=
for v in MONGOLAB APP_PORT ENV; do
err="$err${!v-$v not set$'\n'}"
done
if test -n "$err"
then printf "%s" "$err" >&2; exit 1
fi
echo "All environment variables set"
exit 0
It improves on your solution in that it informs the user of all the required but unset variables at once, avoiding the typical annoying back-and-forth with the script to satisfy it.
We build up the error value by adding a message to it for each unset variable, then if it's non-empty, print it and abort.
The ${!v-...}
construct is an indirection - if there's a variable named $v
, then substitute nothing, else substitute our message.
This uses an array of the required variables, and builds a one-line error message:
#!/bin/bash
set -e
required_vars=(MONGOLAB APP_PORT ENV)
missing_vars=''
for v in "${required_vars[@]}"; do
missing_vars="$missing_vars${!v-$v }"
done
if test -n "$missing_vars"
then printf "Unset required variables: %s\n" "$missing_vars" >&2; exit 1
fi
echo "All environment variables set"
exit 0
#!/bin/bash
set -e
check_vars() {
local m=''
for v in "$@"; do
m="$m${!v-$v }"
done
if test -n "$m"
then printf "Unset required variables: %s\n" "$m" >&2; return 1
fi
}
check_vars MONGOLAB APP_PORT ENV
echo "All environment variables set"
exit 0
Upvotes: 1
Reputation: 3474
Another option is:
[[ $MONGOLAB && $APP_PORT && $ENV ]] || exit 1
If you happen to run a long sanity check with multiple variables, and the code becomes ugly, I suggest to use @anubhava's solution, which is far more elegant.
I usually use a die function instead of exit 1
to be more descriptive to the user in terms of human readable description and exit status code:
##
# die (optional status version): Print a message to
# stderr and exit with either the given status or
# that of the most recent command.
# Usage: some_command || die [status code] "message" ["arguments"...]
#
die() {
local st="$?"
if [[ "$1" != *[^0-9]* ]]; then
st="$1"
shift
fi
warn "$@"
exit "$st"
}
This function is taken from Common utility functions (warn, die) which I encourage you to read further, and maybe use a different version which suites your needs best.
Notice that die
uses a function named warn
which you can find in the same link above.
P.S.
Please note that by convention, environment variables (PATH
, EDITOR
, SHELL
, ...) and internal shell variables (BASH_VERSION
, RANDOM
, ...) are fully capitalized. All other variable names should be lowercase. Since
variable names are case-sensitive, this convention avoids accidentally overriding environmental and internal variables.
Upvotes: 1
Reputation: 785068
You can use a for
loop and check all of them there:
for var in MONGOLAB APP_PORT ENV; do
[[ -z "${!var}" ]] && echo "Missing \$$var"
done
Upvotes: 4