The following code exits with a unbound variable error. How to fix this, while still using the set -o
nounset option?
#!/bin/bash
set -o nounse
How about a oneliner?
[ -z "${VAR:-}" ] && echo "VAR is not set or is empty" || echo "VAR is set to $VAR"
-z
checks both for empty or unset variable
#!/bin/bash
set -o nounset
VALUE=${WHATEVER:-}
if [ ! -z ${VALUE} ];
then echo "yo"
fi
echo "whatever"
In this case, VALUE
ends up being an empty string if WHATEVER
is not set. We're using the {parameter:-word}
expansion, which you can look up in man bash
under "Parameter Expansion".
While this isn't exactly the use case asked for above, I've found that if you want to use nounset
(or -u
) the default behavior is the one you want: to exit nonzero with a descriptive message.
It took me long enough to realize this that I figured it was worth posting as a solution.
If all you want is to echo something else when exiting, or do some cleanup, you can use a trap.
The :-
operator is probably what you want otherwise.
You need to quote the variables if you want to get the result you expect:
check() {
if [ -n "${WHATEVER-}" ]
then
echo 'not empty'
elif [ "${WHATEVER+defined}" = defined ]
then
echo 'empty but defined'
else
echo 'unset'
fi
}
Test:
$ unset WHATEVER
$ check
unset
$ WHATEVER=
$ check
empty but defined
$ WHATEVER=' '
$ check
not empty
You can use
if [[ ${WHATEVER:+$WHATEVER} ]]; then
but
if [[ "${WHATEVER:+isset}" == "isset" ]]; then
might be more readable.
Assumptions:
$ echo $SHELL
/bin/bash
$ /bin/bash --version | head -1
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
$ set -o nounset
If you want a non-interactive script to print an error and exit if a variable is null or not set:
$ [[ "${HOME:?}" ]]
$ [[ "${IAMUNBOUND:?}" ]]
bash: IAMUNBOUND: parameter null or not set
$ IAMNULL=""
$ [[ "${IAMNULL:?}" ]]
bash: IAMNULL: parameter null or not set
If you don't want the script to exit:
$ [[ "${HOME:-}" ]] || echo "Parameter null or not set."
$ [[ "${IAMUNBOUND:-}" ]] || echo "Parameter null or not set."
Parameter null or not set.
$ IAMNULL=""
$ [[ "${IAMUNNULL:-}" ]] || echo "Parameter null or not set."
Parameter null or not set.
You can even use [
and ]
instead of [[
and ]]
above, but the latter is preferable in Bash.
Note what the colon does above. From the docs:
Put another way, if the colon is included, the operator tests for both parameter’s existence and that its value is not null; if the colon is omitted, the operator tests only for existence.
There is apparently no need for -n
or -z
.
In summary, I may typically just use [[ "${VAR:?}" ]]
. Per the examples, this prints an error and exits if a variable is null or not set.