It’s 2018, and this question deserves an update. At least in Bash, as of Bash 4.3-alpha, you can use namerefs to pass function arguments by reference:
function boo()
{
local -n ref=$1
ref="new"
}
SOME_VAR='old'
echo $SOME_VAR # -> old
boo SOME_VAR
echo $SOME_VAR # -> new
The critical pieces here are:
-
Passing the variable’s name to boo, not its value:
boo SOME_VAR, notboo $SOME_VAR. -
Inside the function, using
local -n ref=$1to declare a nameref to the variable named by$1, meaning it’s not a reference to$1itself, but rather to a variable whose name$1holds, i.e.SOME_VARin our case. The value on the right-hand side should just be a string naming an existing variable: it doesn’t matter how you get the string, so things likelocal -n ref="my_var"orlocal -n ref=$(get_var_name)would work too.declarecan also replacelocalin contexts that allow/require that. See chapter on Shell Parameters in Bash Reference Manual for more information.
The advantage of this approach is (arguably) better readability and, most importantly, avoiding eval, whose security pitfalls are many and well-documented.