Reputation: 16428
I have a script that iterates over an array of values, something like this (dumbed down for the purposes of this question) :
COUNTRIES=( ENGLAND SCOTLAND WALES )
for i in ${COUNTRIES[@]}
do
echo "Country is $i "
done
My question is, is it possible to substitute the array dynamically? For example, I want to be able to pass in the array to iterate over at runtime. I've tried the following but I think my syntax might be wrong
COUNTRIES=( ENGLAND SCOTLAND WALES )
ANIMALS=( COW SHEEP DOG )
loopOverSomething()
{
for i in ${$1[@]}
do
echo "value is $i "
done
}
loopOverSomething $ANIMALS
I'm getting line 22: ${$2[@]}: bad substitution
Upvotes: 5
Views: 3926
Reputation: 125788
You can use bash's indirect expansion for this:
loopOverSomething()
{
looparray="$1[@]"
for i in "${!looparray}"
do
echo "value is $i"
done
}
Upvotes: 4
Reputation: 25736
You could use the array as argument in the following way:
COUNTRIES=( ENGLAND SCOTLAND "NEW WALES" )
ANIMALS=( COW SHEEP DOG )
loopOverSomething()
{
for i in "$@"
do
echo "value is $i "
done
}
loopOverSomething "${ANIMALS[@]}"
loopOverSomething "${COUNTRIES[@]}"
Upvotes: 0
Reputation: 295403
This is covered by BashFAQ #006:
We are not aware of any trick that can duplicate that functionality in POSIX or Bourne shells (short of using eval, which is extremely difficult to do securely). Bash can almost do it -- some indirect array tricks work, and others do not, and we do not know whether the syntax involved will remain stable in future releases. So, consider this a use at your own risk hack.
# Bash -- trick #1. Seems to work in bash 2 and up. realarray=(...) ref=realarray; index=2 tmp="$ref[$index]" echo "${!tmp}" # gives array element [2] # Bash -- trick #2. Seems to work in bash 3 and up. # Does NOT work in bash 2.05b. tmp="$ref[@]" printf "<%s> " "${!tmp}"; echo # Iterate whole array.
Upvotes: 0