This has been asked several times, but none of the methods work. I would like to dynamically create arrays with array names taken from the variables. So lets start with just one array for now:

eval ${i}=("1")

results in

./1.sh: line 3: syntax error near unexpected token `('
./1.sh: line 3: `eval ${i}=("1")'

same result with:

$(eval ${i})=('1')
$(eval echo ${i})=('1')
$(eval "echo ${i}")=('1')

I do not want to eval everything, justthe array name. If it is possible I would like to avoid using eval at all

3 Answers 3


eval expects a string as the argument. You can't use ( unquoted, it has a special meaning in shell.

eval "$i=(1 2)"  # Use a string, $i will expand in double quotes.
echo ${aaa[1]}

You can also use declare or typeset instead of eval:

declare -a $i='(1 2)'

You still have to quote the parentheses and spaces.

To avoid eval completely, you can assign one by one:

#! /bin/bash
values=(1 2)
for ((i=0; i<${#values[@]}; ++i)) ; do
    read "$name[$i]" <<< "${values[i]}"
echo ${aaa[1]}
  • I have updated the question
    – meso_2600
    Apr 29, 2015 at 9:21
  • @meso_2600: I updated the answer.
    – choroba
    Apr 29, 2015 at 9:34
  • The read variant is fantastic! At last a alternative to eval! The problem with declare/typeset is that in functions the declared variable is local to the function.
    – t0r0X
    Mar 21, 2017 at 16:36
  • 1
    @t0r0X Use declare -g or declare -x within function to make it global/export.
    – Cromax
    Feb 6, 2018 at 23:54

Here is a way to load the array without using eval. It doesn't use the ( data ) construct - instead it uses an input string with your choice of delimiter - the example uses |

IFS='|' read -a "$i" <<<"1|2   with spaces"
printf '%s\n' "${aaa[@]}"


2   with spaces

You can use declare with dynamic names and values, and variable indirection to reference variables based upon their name. printf '%q' can help you "shell-escape" values so that they can be used during dynamic assignments.

declare -a products=( phone computer )
printf 'Product: %s\n' "${products[@]}"
# Product: phone
# Product: computer
unset products

declare varName='products'
declare -a "${varName}"='( cell\ phone laptop\ computer )'
declare arrayRef="${varName}[@]"
printf 'Product: %s\n' "${!arrayRef}"
# Product: cell phone
# Product: laptop computer
unset "${varName}"

declare -a toCopy=( 'LED TV' '"Smart" car' )
declare -a "${varName}"="( $( printf '%q ' "${toCopy[@]}" ) )"
printf 'Product: %s\n' "${!arrayRef}"
# Product: LED TV
# Product: "Smart" car
unset "${varName}"

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.