fabiomaia
fabiomaia

Reputation: 602

Read input, save it to a dynamically-named variable and check if given input was empty

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.

Upvotes: 1

Views: 623

Answers (3)

fabiomaia
fabiomaia

Reputation: 602

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

Upvotes: 1

clt60
clt60

Reputation: 63922

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"

Upvotes: 2

Uwe
Uwe

Reputation: 728

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.

Upvotes: 3

Related Questions