If I want to check for the null string I would do
[ -z $mystr ]
but what if I want to check whether the variable has been defined at all? O
A shorter version to test undefined variable can simply be:
test -z ${mystr} && echo "mystr is not defined"
https://stackoverflow.com/a/9824943/14731 contains a better answer (one that is more readable and works with set -o nounset
enabled). It works roughly like this:
if [ -n "${VAR-}" ]; then
echo "VAR is set and is not empty"
elif [ "${VAR+DEFINED_BUT_EMPTY}" = "DEFINED_BUT_EMPTY" ]; then
echo "VAR is set, but empty"
else
echo "VAR is not set"
fi
The explicit way to check for a variable being defined would be:
[ -v mystr ]
another option: the "list array indices" expansion:
$ unset foo
$ foo=
$ echo ${!foo[*]}
0
$ foo=bar
$ echo ${!foo[*]}
0
$ foo=(bar baz)
$ echo ${!foo[*]}
0 1
the only time this expands to the empty string is when foo
is unset, so you can check it with the string conditional:
$ unset foo
$ [[ ${!foo[*]} ]]; echo $?
1
$ foo=
$ [[ ${!foo[*]} ]]; echo $?
0
$ foo=bar
$ [[ ${!foo[*]} ]]; echo $?
0
$ foo=(bar baz)
$ [[ ${!foo[*]} ]]; echo $?
0
should be available in any bash version >= 3.0
~> if [ -z $FOO ]; then echo "EMPTY"; fi
EMPTY
~> FOO=""
~> if [ -z $FOO ]; then echo "EMPTY"; fi
EMPTY
~> FOO="a"
~> if [ -z $FOO ]; then echo "EMPTY"; fi
~>
-z works for undefined variables too. To distinguish between an undefined and a defined you'd use the things listed here or, with clearer explanations, here.
Cleanest way is using expansion like in these examples. To get all your options check the Parameter Expansion section of the manual.
Alternate word:
~$ unset FOO
~$ if test ${FOO+defined}; then echo "DEFINED"; fi
~$ FOO=""
~$ if test ${FOO+defined}; then echo "DEFINED"; fi
DEFINED
Default value:
~$ FOO=""
~$ if test "${FOO-default value}" ; then echo "UNDEFINED"; fi
~$ unset FOO
~$ if test "${FOO-default value}" ; then echo "UNDEFINED"; fi
UNDEFINED
Of course you'd use one of these differently, putting the value you want instead of 'default value' and using the expansion directly, if appropriate.
call set without any arguments.. it outputs all the vars defined..
the last ones on the list would be the ones defined in your script..
so you could pipe its output to something that could figure out what things are defined and whats not