How to test if a variable exists and has been initialized

24,304

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.)

Share:
24,304
ogs
Author by

ogs

Updated on July 22, 2022

Comments

  • ogs
    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?