Search code examples
bashvariablesdynamicdeclare

How can I read out the values of dynamically declared bash variables?


I have some trouble with a bash script, maybe someone can help me.

Inside my script, I defined variables dynamically using a loop like this:

somecolors="red yellow green blue" # read out of a file, may vary
for color in $(echo $somecolors); do
    # Actually, here is more code that generates the value I 
    # want to set for this variable, that is being written
    # into "$value"
    declare use_color_$color=$value
done

The result is that four variables have been defined:

use_color_red=1
use_color_yellow=1
use_color_green=1
use_color_blue=1

So far so good. But how can I dynamically read these? I thought of suing a "for" loop. For example:

for color in $(echo $colors); do
    echo $use_color_${color}
done

But this does not work.

How can I compose two variable names to a single one?

Thanks in advance!


Solution

  • Better use indexed and associative arrays instead. Referencing and dereferencing variable variables that way is really wrong.

    somecolors=(red yellow green blue)
    declare -A use_color
    
    for color in "${colors[@]}"; do
        use_color[$color]=$value  ## Or do you mean use_color[$color]=$color?
    done
    

    Granting $value == 1, when you do echo "${use_color[red]}" you'd get 1.

    One variation:

    declare colors=(red yellow green blue)
    
    declare -A use_color    
    use_color[red]=1
    use_color[yellow]=1
    use_color[green]=1
    use_color[blue]=1
    
    for color in "${colors[@]}"; do
        echo "use_color[$color]=${use_color[$color]}"
    done
    

    Output:

    use_color[red]=1
    use_color[yellow]=1
    use_color[green]=1
    use_color[blue]=1
    

    Similarly:

    declare -A use_color=([red]=1 [yellow]=1 [green]=1 [blue]=1)
    
    for color in "${!use_color[@]}"; do
        echo "use_color[$color]=${use_color[$color]}"
    done
    

    Output:

    use_color[yellow]=1
    use_color[red]=1
    use_color[blue]=1
    use_color[green]=1