My environment can have a flexible number of variables defined with the following format:


I now would like to iterate over the variables as long as they exists. In pseudo code:

while [exists "Var"$i"Value"]; do
 echo "found variable, now doing some more complex processing logic"
 #do some more stuff
 i=$((i + 1)) 

I do I make this work in bash (without using arrays)?


Use a nameref. They work sort of like pointers to other variables (in Bash 4.3 and later):


for (( i=1 ; ; i++ )); do
    n="Var${i}Value"                # the name of var
    declare -n p="$n"               # reference to the var
    [ "${p+x}" ] || break           # see if it exists
    echo "$n: '$p'"

"${p+x}" evaluates to x if the variable pointed to by p exists, so this deals with set but empty variables, too.

Alternatively, use indirect variable expansion ${!n}, which refers to the variable named by n.

for (( i=1 ; ; i++ )); do
    n="Var${i}Value"                # the name of var
    [ "${!n+x}" ] || break          # see if it exists
    echo "$n: '${!n}'"

But really, you should use an array. None of the three choices here are standard, but arrays are by far the most logical.

VarValue=( A B C )

for value in "${VarValue[@]}"; do
    # use "$value" here
    printf 'Value is "%s"\n' "$value"

See also:


This seems to work:

for ((i=1;i<=3;i++)); do
    eval echo "$"$(eval echo Var${i}Value)

There's a joke in there somewhere about it being horribly eval...

  • I suspect I probably don't really need the inner eval, but I'm not interested in optimizing this. – Rich Mar 19 at 17:25
  • Thanks for the quick reply Rich. The echo statement is meant as a placeholder for some more complicated work, therefore I'd still need a conditional statement which is what I'm struggling with. I'll update the question to be more clear. – Bernie Lenz Mar 19 at 17:28

To check if a variable is set, see How do I check if a variable exists in an 'if' statement? ([ -v "Var${i}Value" ] (ksh/zsh/bash) or eval "[ -n \"\${Var${i}Value+set}\" ]" (POSIX)).

Now, to loop over the variables whose name matches a pattern, in zsh, you could do:

for varname in ${(Mk)parameters:#Var<->Value}; do
  something with "$varname" and its value: "${(P)varname}"

To process them in numeric order, add the n parameter expansion flag (change Mk to Mkn).

With bash:

readarray -t list < <(compgen -v | grep -xE 'Var[[:digit:]]+Value')
for varname in "${list[@]}"; do
  something with "$varname" and its value: "${!varname}"

Or replacing the readarray with split+glob to avoid using an array:

IFS=$'\n' # split on newline
for varname in $(compgen -v | grep -xE 'Var[[:digit:]]+Value'); do
  something with "$varname" and its value: "${!varname}"

To process them in numeric order and assuming your sort is GNU sort, pipe the output of grep into sort -V.

  • Question explicitly states "without using arrays", and your bash solution makes an array. – Rich Mar 19 at 18:35
  • @Rich, I interpret the without using arrays as meaning without replacing the varxvalue with varvalue[x]. I've added a split+glob variant that avoids the array variable. – Stéphane Chazelas Mar 19 at 18:37
  • And that would be a highly accurate description of exactly what you're doing in your solution - aside from the fact you also changed the name from varvalue[x] to list[x]. – Rich Mar 19 at 18:38
  • @Rich, no list holds the list of variable names, so we can loop over them later, not their values. – Stéphane Chazelas Mar 19 at 18:49
  • I see you added a split+glob solution to your answer. Thank you for recognizing your error in working to the specification! – Rich Mar 19 at 19:00

For loop can be used if variables are known:



for i in var1 var2 var3
           echo " This is $i"
           #More commands.


 This is var1
 This is var2
 This is var3

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.