Pattern: Malformed variable expansion via indirection
Issue: -
You can expand a variable var_1
with ${var_1}
, but you can not generate the string var_1
with an embedded expansion, like ${var_$n}
.
Instead, if at all possible, you should use an array. Bash and ksh support both numerical and associative arrays.
If you can't use arrays, you can indirectly reference variables by creating a temporary variable with its name, e.g. somevar="var_$n"
and then expanding it indirectly with ${!somevar}
. This will give the contents of the variable var_1
.
If using POSIX sh, where neither arrays nor ${!var}
is available, eval
can be used. You must be careful in sanitizing the data used to construct the variable name to avoid arbitrary code execution.
Example of incorrect code:
var_1="hello world"
n=1
echo "${var_$n}"
Example of correct code:
Bash/ksh:
# Use arrays instead of dynamic names
declare -a var
var[1]="hello world"
n=1
echo "${var[n]}"
or
# Expand variable names dynamically
var_1="hello world"
n=1
name="var_$n"
echo "${!name}"
POSIX sh:
# Expand dynamically with eval
var_1="hello world"
n=1
eval "tmp=\$var_$n"
echo "${tmp}"