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=$1
to declare a nameref to the variable named by$1
, meaning it’s not a reference to$1
itself, but rather to a variable whose name$1
holds, i.e.SOME_VAR
in 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.declare
can also replacelocal
in 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.