Test for a Bash variable being unset, using a function

DaveP picture DaveP · May 17, 2009 · Viewed 48.8k times · Source

A simple Bash variable test goes:

${varName:?    "${varName} is not defined"}

I'd like to re-use this, by putting it in a function. How please?

Following fails

#
# Test a variable exists
tvar(){
 val=${1:?    "${1}    must be defined, preferably in $basedir"}
 if [ -z ${val}  ]
     then 
     echo Zero length value 
 else
     echo ${1} exists, value ${1}
 fi
}

I.e. I need to exit if the test fails.

Answer

Dennis Williamson picture Dennis Williamson · Sep 24, 2009

Thanks to lhunath's answer, I was led to a part of the Bash man page that I've overlooked hundreds of times:

    When  not performing substring  expansion, bash tests for a parameter that
    is unset  or null; omitting the colon results in a test only for a parame‐
    ter that is unset.

This prompted me to create the following truth table:


                | unset |   set    | set and  | meaning
                |       | but null | not null |
    ============+=======+==========+==========+=============================
     ${var-_}   |   T   |     F    |    T     | not null or not set
    ------------+-------+----------+----------+-----------------------------
     ${var:-_}  |   T   |     T    |    T     | always true, use for subst.
    ------------+-------+----------+----------+-----------------------------
     $var       |   F   |     F    |    T     | var is set and not null
    ------------+-------+----------+----------+-----------------------------
     ${!var[@]} |   F   |     T    |    T     | var is set

This table introduces the specification in the last row. The Bash man page says "If name is not an array, expands to 0 if name is set and null otherwise." For purposes of this truth table, it behaves the same even if it's an array.