I have a program that acts like a menu. It has an associative array called config
such as:
declare -A config=( [h]="?" [c]="?" [x]="?" [l]="?" [t]="?" [n]="?" )
In the main loop there's a check to see if all of the values have been configured, like:
if [ "${config[h]}" == "Y" ] && [ "${config[c]}" == "Y" ] && [ "${config[l]}" == "Y" ] && [ "${config[x]}" == "Y" ] && [ "${config[t]}" == "Y" ] && [ "${config[n]}" == "Y" ];
Now, when I finish one run, I unset and redeclare the array.
unset config; declare -A config=( [h]="?" [c]="?" [x]="?" [l]="?" [t]="?" [n]="?" )
However, the array doesn't seem to be re-declared properly. This is because when I configure just one of the values, [C]=Y
for example, the if
statement passes. I know for sure it does because the body of the if
statement changes some of the text color. I believe it's because the rest of the indices aren't actually set="?", so the if
statement is reduced to just [ "${config[c]}" == "Y"]
which is be true
. I know this since when I echo $config[@]
inside the body of the if
statement, sure enough I only see one "Y" instead of five. How do I get the array to redeclare properly?
EDIT
Thank you for your attention;
Values are set to Y after some user input. This part I'm very confident about and thus omitted from my question. They all follow this format:
read ch if [ $ch == "Hosts" ]; then while true; do nano listHosts echo -en "Commit this list of Hostnames? [Y|N to re-edit]: " read yn if [ $yn == "Y" ] || [ $yn == "y" ] || [ $yn == "yes" ]; then break elif [ $yn == "N" ] || [ $yn == "n" ] || [ $yn == "no" ]; then continue fi done config[h]="Y"
Regarding Kusalanda's comment, I checked for incorrect casing but it's consistently lower-case 'c'. As well, yes, I meant
${config[@]}
.Declare -p sheds some light:
declare -a config='([0]="Y")'
How come -p says I used lowercase a? The calls are in this order:
unset config
declare -A config=( [h]="?" [c]="?" [x]="?" [l]="?" [t]="?" [n]="?" )
Then I set $ch="Commands" via read
;
elif [ $ch == "Commands" ]; then
while true; do
nano iSet
echo -en "Commit this list of commands? [Y|N to re-edit]: "
read yn
if [ $yn == "Y" ] || [ $yn == "y" ] || [ $yn == "yes" ]; then
break
elif [ $yn == "N" ] || [ $yn == "n" ] || [ $yn == "no" ]; then
continue
fi
done
config[c]="Y"
declare -p config
I tried to recreate in a smaller script as per Bodo's suggestion:
dec() {
declare -A config=( [h]="?", [c]="?" )
}
test() {
declare -p config
if [ "${config[h]}" == "Y" ] && [ "${config[c]}" == "Y" ]; then
echo "Yup"
fi
}
dec
config[h]="Y"; config[c]="Y"
unset config
dec
config[h]="Y"
test
And just like in my other script, the if
resolves to true:
declare -a config='([0]="Y")'
Yup
Y
, and (b)$config[@]
... Did you mean"${config[@]}"
?[c]="Y"
rather than[C]=Y
? Also, did you mean you printed${config[@]}
rather than$config[@]
?declare
a variable inside a function, it makes that variable local to the function. It is an issue in the test code that you show, but we don't know whether you have the same issue in your real code.