How to test if a variable exists and has been initialized
Solution 1
You probably want to use indirect expansion: ${!variable}
and then -n
to check if it has been defined:
The indirect expansion consists in calling a variable with another variable. That is, as the variable name may be changing, instead of saying $a
we say ${!var}
and var=a
.
$ cat a
var1_ID=0x04
var2_ID=0x05
var3_ID=0x06
var4_ID=0x09
for i in {1..5}; do
v="var${i}_ID"
if [ -n "${!v}" ]; then # <-- this expands to varX_ID
echo "$v set to value: ${!v}"
else
echo "$v not set"
fi
done
If we execute, we get:
$ ./a
var1_ID set to value: 0x04
var2_ID set to value: 0x05
var3_ID set to value: 0x06
var4_ID set to value: 0x09
var5_ID not set
From man test
:
-n STRING
the length of STRING is nonzero
Solution 2
Use Parameter expansion:
: ${var:?}
Remove the colon if the empty string is a valid value (i.e. you only want to test for definedness).
: ${var?}
If you don't want the script to stop on the problem, you can use
if [[ ${var:+1} ]] ; then
# OK...
else
echo Variable empty or not defined. >&2
fi
Solution 3
In bash
4.2, you can use the -v
operator in a conditional expression to test if a variable with the given name is set.
if [[ -v ${1}_ID ]]; then
echo "${1}_ID is set"
foo=${1}_ID
echo "${!foo}"
fi
You still need indirect parameter expansion to get the value.
In bash
4.3 you can use a named reference to make working with it easier.
declare -n param=${1}_ID
if [[ -v param ]]; then
echo "${1}_ID"
echo "$param"
fi
(param
will behave exactly like the variable it references. I don't know if there is an easy way, short of parsing the output of declare -p param
, to get the name of the variable it references.)
ogs
Updated on July 22, 2022Comments
-
ogs almost 2 years
I have to execute a function which has to to test if a variable has been correctly defined in the bash and must use its associated value.
For instance, these variables are initialized at the top of the script.
#!/bin/bash var1_ID=0x04 var2_ID=0x05 var3_ID=0x06 var4_ID=0x09
I would like to call the script named test as follows:
./test var1
The current implemented function is:
function Get() { if [ $1"_ID" != "" ]; then echo "here" echo $(($1_ID)) else exit 0 fi }
I don't understand why I obtain
here
even if I enter./test toto
or something else.Do I need to use a specific command, such as
grep
?