I suggest building Bash from the git devel branch and using typeset -n
like most other sane shells with arrays do. All other solutions involving functions and arrays require either eval
or exploiting quirky undocumented behaviours. Both require about equal care and there isn't necessarily an advantage to one over the other.
Here is a general example which demonstrates just about everything you can do indirectly without eval. Namespace collisions are still possible.
isSubset() {
local -a 'xkeys=("${!'"$1"'[@]}")' 'ykeys=("${!'"$2"'[@]}")'
set -- "${@/%/[key]}"
(( ${#xkeys[@]} <= ${#ykeys[@]} )) || return 1
local key
for key in "${xkeys[@]}"; do
[[ ${!2+_} && ${!1} == "${!2}" ]] || return 1
done
}
a=(abc def [4]=ghi jkl)
b=(abc def [4]=ghi jkl)
c=(abc [3]=def [6]=ghi xyz)
isSubset a b
echo $? # 0
isSubset b c
echo $? # 1
This is really eval
in disguise in some respects. Most people are unaware that they are effectively performing eval any time they pass variable names to builtins and arithmetic expressions. You have to always ensure that variable names and indexes are controlled internally and never influenced by user input or other side-effects that you can't guarantee the results of.
Judging by your misuse of wordsplitting and quoting, you should probably just switch to a different language. Bash isn't really meant to deal with safe encapsulation.