Reputation: 1031
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
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
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