spaghettiwestern
spaghettiwestern

Reputation: 393

Bash for loop if statement array name referenced as variable

The if [ {$i[0]} = "true" ] below is failing. I can't seem to figure out how to get the correct formatting for {$i[0]} in the if statement.

#!/bin/bash
foo=bar1,bar2

for i in ${foo//,/" "}
do
declare -a ${i}='(true null null null)'
done

for i in ${foo//,/" "}
do
if [ {$i[0]} = "true" ]
then echo "yes"
eval "echo \${$i[*]}"
else echo "no"
fi
done

I had a somewhat of related problem that someone was kind enough to help me with Bash echo all array members when array is referenced as a variable in a loop

Thanks for any help!

Upvotes: 1

Views: 2860

Answers (1)

Dennis Williamson
Dennis Williamson

Reputation: 360113

You're going to have to use eval here, too, but I would again recommend a different overall design.

if [ "$(eval "echo \${$i[0]}")" = "true" ]

Edit:

Proposal for redesign (uses an imaginary scenario extrapolated from the little bit I've seen of what you're doing):

#!/bin/bash
# sample input: $1=foo,bar,baz
saveIFS=$IFS
IFS=','       # word splitting will be done using a comma as the delimiter
names=($1)    # store the names for cross reference or indirection
IFS=$saveIFS

# Constants:
declare -r heater=0
declare -r exhaust=1
declare -r light=2
declare -r rotation=3

# deserialize and serialize:

# initialize settings
for ((i=0; i<${#names}; i++))
do
    declare ${names[i]}=$i    # setup indirection pointers
    config[i]="null null null null"
done

# by index:
vals=(${config[0]})       # deserialize
echo ${vals[light]}       # output value
vals[light]="false"       # change it
config[0]=${vals[@]}      # reserialize

# by name:
vals=(${config[$foo]})
echo ${vals[light]}       # output value

# by indirection:
vals=(${config[${!names[0]}]})
echo ${vals[light]}       # output value

# iteration using indirection
for name in ${names[@]}
do
    echo "Configuration: $name"
    echo "  all settings: ${config[${!name}]}"
    vals=(${config[${!name}]})
    for setting in heater light # skipping exhaust and rotation
    do
        echo "    $setting: ${vals[${!setting}]}"
    done
done

This may give you some ideas and principles that you can make use of. If you're using Bash 4, you could use associative arrays which would greatly simplify this type of thing. You can also use functions to do some simplification.

Upvotes: 2

Related Questions