Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash function to check for unset and blank variables

Tags:

bash

I'm writing a bash function to check for blank or unset variables.

function exit_if_var_does_not_exist {
    TMP_NAME=$1
    TMP_VALUE=`echo $TMP_NAME`
    if [ -z ${TMP_VALUE+x} ]; then
        echo "Variable [${TMP_NAME}] is unset. Exiting."
        exit 1
    else
        if [ ${TMP_VALUE} = "" ]; then
            echo "Variable [${TMP_NAME}] is set to ''. Exiting."
            exit 1
        fi
    fi
    echo "Variable [${TMP_NAME}] is set to ${TMP_VALUE}"
}

VAR=Test
exit_if_var_does_not_exist VAR
BLANK=
exit_if_var_does_not_exist BLANK

This does not give me the expected output in TMP_VALUE. Can someone please help me with what I'm missing here?

-bash-3.2$ ./x.sh
Variable [VAR] is set to VAR
Variable [BLANK] is set to BLANK
like image 949
qwerty Avatar asked Oct 28 '25 06:10

qwerty


1 Answers

The problem with the empty test block is that at no point in this snippet do you ever actually get the value of the originally named variable.

When you use TMP_NAME=$1 you assign the name of the input variable to TMP_NAME and then

TMP_VALUE=`echo $TMP_NAME`

just assigns that name to TMP_VALUE. Effectively you just ran TMP_VALUE=$1.

So you aren't testing for whether the originally named variable has contents anywhere here.

To do that you need to use indirect expansion.

Namely TMP_VALUE=${!TMP_NAME} or TMP_VALUE=${!1}.

Side comment your "unset" test block at the top can never trigger.

TMP_VALUE can never be unset because you assign to it. Even TMP_VALUE= marks the variable as "set". So that bit is useless. Though, and thank David C. Rankin for trying long enough to make me think of this, you can use an indirect expansion trick to make this work.

[ -z "${!TMP_NAME+x}" ] will return true for any set variable named in TMP_NAME and false for an unset variable.

That all said if what you want to do is error if a variable is unset or blank the shell has you covered. Just use

: "${VAR:?Error VAR is unset or blank.}" || exit 1

Finally, as David C. Rankin points out inside [ you need to quote expansions that might disappear when they change the meaning of tests (you see this in the -z test above) as well as here.

So [ ${TMP_VALUE} = "" ] needs to be [ "${TMP_VALUE}" = "" ] because is TMP_VALUE is empty the first version would become a syntax error because [ = "" ] isn't a valid invocation of test/[.

like image 61
Etan Reisner Avatar answered Oct 29 '25 22:10

Etan Reisner



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!