Varun J.P
Varun J.P

Reputation: 29

In Shell script how can i loop through a variable containing other variables

I need to create a loop. The loop variable contains other variables. This is what i have tried

parentClients="name1 name2"
effectedClients="value1 value2"
otherClients="something1 something2 something3"
client_types="$parentClients $effectedClients $otherClients"
do
   echo $client
#this should print "parentClients" in 1st iteration and "effectedClients" in second and so on.
   for ct in $client
      do
        echo $ct
#this should print name1 name2 nd so on.
      done
      echo "done with one set"
done

The problem with this code is that its resolving all the values and assigning to the variable client_types

Upvotes: 1

Views: 44

Answers (1)

John1024
John1024

Reputation: 113814

Using bash

With bash, we can use arrays and indirection:

parentClients=(name1 name2)
effectedClients=(value1 value2)
otherClients=(something1 something2 something3)
client_types=(parentClients effectedClients otherClients)
for client in "${client_types[@]}"
do
   echo "client=$client"
   c=$client[@]
   for ct in "${!c}"
   do
      echo "  ct=$ct"
   done
   echo "done with one set"
done

This produces the output:

client=parentClients
  ct=name1
  ct=name2
done with one set
client=effectedClients
  ct=value1
  ct=value2
done with one set
client=otherClients
  ct=something1
  ct=something2
  ct=something3
done with one set

The statement parentClients=(name1 name2) creates an array named parentClients with values name1 and name2. The expression ${!c} uses indirection to access the array whose name is given by c.

Using POSIX shell

With a POSIX shell, we must use variables instead of arrays and, in place of indirection, we use eval:

parentClients="name1 name2"
effectedClients="value1 value2"
otherClients="something1 something2 something3"
client_types="parentClients effectedClients otherClients"
for client in $client_types
do
   echo "client=$client"
   eval "client_list=\$$client" # Potentially dangerous step
   for ct in $client_list
   do
      echo "  ct=$ct"
   done
   echo "done with one set"
done

Because eval requires some trust in the source of the data, it should be used with caution.

This produces the output:

client=parentClients
  ct=name1
  ct=name2
done with one set
client=effectedClients
  ct=value1
  ct=value2
done with one set
client=otherClients
  ct=something1
  ct=something2
  ct=something3
done with one set

Upvotes: 1

Related Questions