Coli
Coli

Reputation: 1031

parameter substitution inside function

I need to set a default value (y) when the user hits enter in read

validate() {
    local validated=false
    while [ "$validated" != "true" ]; do
            read -p "$1 " $2
            $2=${2:-y}
            if [[ "$2" == "y" || "$2" == "n" ]]; then
                    validated=true
            fi
    done
}

When I run this function with validate "text" test and skip the read with enter, the error test=test: command not found appears. How can I use the substitution with function arguments?

Upvotes: 3

Views: 155

Answers (2)

user1934428
user1934428

Reputation: 22225

There are several problems, but you can see it easiest with your statement

$2=${2:-y}

Let's assume that the user passes as second argument the string FOO. This statement becomes

FOO=FOO

Certainly not what you expect. Now assume that no second argument is being passed. In this case, $2 evaluates to the empty string and $2=${2:-y} evaluates to y. Hence, this statement becomes

=y

which is even syntactically incorrect. With this in mind, you can see that your

read -p "$1 " $2

doesn't make sense either.

When writing a function, the best way is to not use positional parameters in the algorithm itself (unless you have good reason to do so), but assign them to variables and use the variables consistently, as @janos demonstrated in his proposed solution. It is not only safer, but makes your program easier to understand as well.

Upvotes: 1

janos
janos

Reputation: 124648

To write a value to a variable with a dynamic name, you can use printf -v "$name" "$value". This should be closer to what you want, though I suspect some further confusion and follow-up questions:

validate() {
    local message=$1
    local out=$2
    local validated=false answer

    while [ "$validated" != true ]; do
        read -p "$message " answer
        answer=${answer:-y}
        if [[ "$answer" == "y" || "$answer" == "n" ]]; then
            validated=true
        fi
    done

    printf -v "$out" "$answer"
}

Upvotes: 2

Related Questions