Skip to content
Joachim Ansorg edited this page Nov 12, 2021 · 6 revisions

To expand via indirection, use name="foo$n"; echo "${!name}".

Problematic code:

var_1="hello world"
n=1
echo "${var_$n}"

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}"

Rationale:

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, and an example is shown above.

If you can't use arrays, you can indirectly reference variables by creating a temporary variable with its name, e.g. myvar="var_$n" and then expanding it indirectly with ${!myvar}. 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.

Exceptions:

None

Related resources:

ShellCheck

Each individual ShellCheck warning has its own wiki page like SC1000. Use GitHub Wiki's "Pages" feature above to find a specific one, or see Checks.

Clone this wiki locally