Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In a function Bash: how to check if an argument is a set variable?

I want to implement a bash function which test is the 1st argument is actually a variable, defined somewhere.

For instance, in my .bashrc :

customPrompt='yes';
syntaxOn='no';
[...]
function my_func {
    [...]
    # I want to test if the string $1 is the name of a variable defined up above
    # so something like: 
    if [[ $$1 == 'yes' ]];then 
         echo "$1 is set to yes";
    else
         echo "$1 is not set or != to yes";
    fi
    # but of course $$1 doesn't work
}

output needed :

$ my_func customPrompt
> customPrompt is set to yes
$ my_func syntaxOn
> syntaxOn is set but != to yes
$ my_func foobar
> foobar is not set

I tried a lot of test, like -v "$1", -z "$1", -n "$1", but all of them test $1 as a string not as a variable. (please correct me if I make not myself clear enought)

like image 428
4wk_ Avatar asked Jul 24 '14 09:07

4wk_


3 Answers

In the bash you can use the indirect variable subtituion.

t1=some
t2=yes
fufu() {
    case "${!1}" in
        yes) echo "$1: set to yes. Value: ${!1}";;
        '')  echo "$1: not set. Value: ${!1:-UNDEF}";;
        *)   echo "$1: set to something other than yes. Value: ${!1}";;
    esac
}

fufu t1
fufu t2
fufu t3

prints

t1: set to something other than yes. Value: some
t2: set to yes. Value: yes
t3: not set. Value: UNDEF

The ${!variablename} in bash mean indirect variable expansion. Described in the e.g. https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html

Whrere:

The basic form of parameter expansion is ${parameter}. The value of parameter is substituted. The braces are required when parameter is a positional parameter with more than one digit, or when parameter is followed by a character that is not to be interpreted as part of its name.

If the first character of parameter is an exclamation point (!), a level of variable indirection is introduced. Bash uses the value of the variable formed from the rest of parameter as the name of the variable; this variable is then expanded and that value is used in the rest of the substitution, rather than the value of parameter itself. This is known as indirect expansion. The exceptions to this are the expansions of ${!prefix } and ${!name[@]} described below. The exclamation point must immediately follow the left brace in order to introduce indirection.

Also, check this: https://stackoverflow.com/a/16131829/632407 how to modify in a function a value of the variable passed indirectly.

like image 190
jm666 Avatar answered Oct 22 '22 21:10

jm666


You can check variable set or not by simply like

if [[  $var ]]
then
    echo "Sorry First set variable"
else
    echo $var  
fi

You can do something like this for your script

customPrompt='yes';
syntaxOn='no';
function my_func 
{
      if [[ ${!1} ]];then 
          echo "$1 is set to ${!1}";
      else
         echo "$1 is not set";
      fi
}
my_func customPrompt
my_func syntaxOn
my_func foobar

Output:

customPrompt is set to yes
syntaxOn is set to no
foobar is not set

You can customize the function as per you requirement by simply making some comparison conditions.

For more details you can check this answer

like image 2
Jayesh Bhoi Avatar answered Oct 22 '22 20:10

Jayesh Bhoi


If you really want to check if your variable is set or unset (not just empty), use this format:

function my_func {
    if [[ -z ${!1+.} ]]; then 
         echo "$1 is not set."
    elif [[ ${!1} == yes ]]; then
         echo "$1 is set to yes"
    else
         echo "$1 is set to \"${!1}\"."
    fi
}
like image 1
konsolebox Avatar answered Oct 22 '22 19:10

konsolebox