tags:

views:

54

answers:

1

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 http://stackoverflow.com/questions/3824681/bash-echo-all-array-members-when-array-is-referenced-as-a-variable-in-a-loop

Thanks for any help!

+2  A: 

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.

Dennis Williamson
That worked thanks. What did you have in mind as a different design? I am all ears. I know you talked about using strings instead of array's. Is your idea to do `bar1=true,null,null,null` instead and use "Shell Parameter Expansion" like I did with `${foo//,/" "}` to read, write and modify my stored parameters?
spaghettiwestern
@spaghettiwestern: See my edit for some ideas. It's best to avoid `eval` if you can for [security reasons](http://mywiki.wooledge.org/BashFAQ/048).
Dennis Williamson
Again Dennis thanks a bunch for your help. I will look over your suggestion.
spaghettiwestern