7

When trying to check if a variable is set or unset in bash, I found the bash conditional expression: -v (here: True if the shell variable is set (has been assigned a value).). I try the code:

#!/bin/bash
VAR="not-empty"
if [ ! -v "$VAR" ]; then
        echo "unset"
else 
        echo "set: $VAR"
fi

But, the output is unset even i assigned VAR at the begin of code.

I found How to check if a variable is set in Bash? question, and tried to replace ! -v by -z to check the string variable VAR. The output is set: non-empty.

Anyone can help to explain the first case (using -v expression) why the output is unset?

My bash version:

GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu) Copyright (C) 2019 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html

0

2 Answers 2

9

You don't need the $ when checking if it is set and so:

if [[ ! -v VAR ]]; then
    echo "unset"
else 
    echo "set: $VAR"
fi
Sign up to request clarification or add additional context in comments.

3 Comments

Can you explain why it works when we don't use $ ?
$ normally expands a variable or command. In this instance, we are not expanding.
It's not that you can't use $, but that the argument to -v is supposed to take the name of a variable as its argument. If you want to check if VAR is set, then VAR, not the expansion of $VAR, is the argument you want.
4

Checking the manual for bash, I found:

   -v varname
          True if the shell variable varname is set (has been assigned a value).

But the problem is:

VAR="not-empty"
[ ! -v "$VAR" ]

is not incorrect, but performs a different test. It checks if there is a variable named 'not-empty' that is set.

You should test like this:

#!/bin/bash
VAR="not-empty"
if [ ! -v VAR ]; then
        echo "unset"
else 
        echo "set: $VAR"
fi

1 Comment

This is a better answer, except that it's using [ instead of [[. When you absolutely require that a shell-builtin test implementation be used and are targeting a ksh-family shell such as bash, [[ is the better choice: Even though modern shells do generally have built-in [ implementations, that's generally a performance enhancement and the only standard-guaranteed behaviors are those specified for /usr/bin/[, which (as an external command) can't see shell variables and isn't specified to have a -v.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.