dkumar
dkumar

Reputation: 338

How to double substitute an array variable in bash

I want to cross-compile an array of libs against different architectures using a shell script.

An array of libraries:

LIBS=(FOO ZOO)

Array of cores specific to each lib(for which this library to be cross-compiled.)

FOO_CORES=(ARM_CM3 ARM_CM4 ARM_CR4)

ZOO_CORES=(ARM_CR4)

Basically, I would like to see this happening:

  make FOO CORE=ARM_CM3
  make FOO CORE=ARM_CM4
  make FOO CORE=ARM_CR4

  make ZOO CORE=ARM_CR4

I can run a for-loop which can iterate through the array of libraries. But how do I refer to each library-specific array of cores? I can get each library-specific core name variable using double-substitution... but that's it! Not sure whether double-substitution works with arrays as well.

for lib in ${LIBS[@]};do
  eval "lib_name=${lib}_CORES"
  cores_list=${!lib_name}
  echo $lib_name $cores_list
done

Output:

FOO_CORES ARM_CM3
ZOO_CORES ARM_CR4

Upvotes: 1

Views: 472

Answers (2)

Benjamin W.
Benjamin W.

Reputation: 52132

If you have Bash 4.3 or newer, you can use namerefs:

for lib in "${LIBS[@]}"; do
    declare -n list=${lib}_CORES
    for core in "${list[@]}"; do
        make "$lib" "$core"
    done
done

The key is the declare -n line: list will behave as if it were the parameter whose name has been assigned to it.

Upvotes: 3

chepner
chepner

Reputation: 531125

For the purposes of indirect parameter expansion, the parameter "name" consists of both the array name and the desired index.

for lib in "${LIBS[@]}"; do
  a=${lib}_CORES
  t="$a[@]"
  printf '%s\n' "$a"
  printf ' %s\n' "${!t}"
done

produces

FOO_CORES
 ARM_CM3
 ARM_CM4
 ARM_CR4
ZOO_CORES
 ARM_CR4

Upvotes: 1

Related Questions