1

Consider a generic ask() function that asks the user a question, reads the input and saves it in a variable named according to one of the function's arguments.

ask() {
    local question="$1"
    local varname="$2"

    echo "$question"
    read $varname
}

Suppose I want to ask the user what is his favourite pet and store the answer in a variable named $pet. Usage would be as follows:

ask "What is your favourite pet?" pet

What I want to do and need help with is check if the user's input was empty, and in that case set the user's input to some string. I would be able to do this easily if the name of the variable the user's input is stored in was constant, like so:

if [ -z "$pet" ]; then
    pet="foo"
fi

However the name of the variable I want to check whether or not is empty is whatever I pass in as the second argument. How can I check if the variable (named as per the value of $varname) containing the user's input is empty? The solution should be as portable and standard as possible, and must work under bash and zsh specifically.

fabiomaia
  • 592
  • 9
  • 19
  • This may be of help to you: http://stackoverflow.com/questions/1921279/how-to-get-a-variable-value-if-variable-name-is-stores-as-string – Noctua May 31 '13 at 21:16

3 Answers3

3

In bash, ${!varname} gives you the value of the variable whose name is the value of $varname, but as far as I know, this syntax is not supported by zsh. If you want something that works in both bash and zsh, you may have to use the oldfashioned eval value=\${$varname} and then check $value. You should only use this if you know in advance that the value of $varname is a legal variable name; otherwise this is unsafe.

Uwe
  • 718
  • 4
  • 9
2

maybe:

ask() {
        name=$1;shift
        read -r -p "$@ >" var
        eval "$name='$var'"
}

ask pet "What is your favourite pet?"
pet=${pet:-foo}

echo "PET: $pet"
clt60
  • 62,119
  • 17
  • 107
  • 194
1

Based on the input thus far I managed to get a satisfying solution.

eval varname_tmp=\$$varname

if [ -z "$varname_tmp" ]; then
    eval "$varname=foo"
fi
fabiomaia
  • 592
  • 9
  • 19