Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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:

#!/bin/bash
i="aaa"
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

share|improve this question
up vote 3 down vote accepted

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

i=aaa
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
name=aaa
values=(1 2)
for ((i=0; i<${#values[@]}; ++i)) ; do
    read "$name[$i]" <<< "${values[i]}"
done
echo ${aaa[1]})
share|improve this answer
    
I have updated the question – meso_2600 Apr 29 '15 at 9:21
    
@meso_2600: I updated the answer. – choroba Apr 29 '15 at 9:34
    
I have accepted your answer – meso_2600 Apr 29 '15 at 13:18

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 |

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

Output:

1
2   with spaces
share|improve this answer

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.

#!/bin/bash
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}"
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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