I want to write a function similar to the read built-in, where I pass a variable name as an argument, and the function returns its result into the variable named.
I tried doing it like this:
GLOBAL_VAR=0
foo() {
local var="$1"; shift
local result
# ...
(( GLOBAL_VAR++ ))
# ...
eval "${var}=\${result}"
}
There is a problem with the above, though: the above doesn’t work if I call foo with the first argument var or result, because then the assignment becomes to the local variable defined inside foo instead of its caller. In effect, this leaks the implementation of foo.
If I use a nameref instead (local -n), running foo var results in a warning message, while foo result returns nothing to the caller, because the result variable is assigned within the function. And I cannot just rename the variable to something that will not conflict, because I actually intend to perform recursion here, so the variable will inevitably clash with itself. Namerefs don’t help with my problem at all.
I cannot use a subshell either, because then any modifications to global variables will be lost.
Is there a way to assign to a dynamically-named variable as defined in the context of the caller?
(In other words, I am looking for the bash equivalent of Tcl’s upvar and/or uplevel.)