Problem
Sourcing the result of declare -p
for a valid Bash associative array in which keys contain square brackets results in a bad array subscript error.
Testing Procedure
Do:
$ declare -A array
$ key='var[0]'
$ array["$key"]=37
$ echo ${array["$key"]}
37
$ declare -p array > def.sh
$ cat def.sh
declare -A array='(["var[0]"]="37" )'
$ . def.sh
bash: [var[0]]=37: bad array subscript
In the above code, note:
- I am able to specify a key that contains square brackets:
var[0]
- The key is quoted for setters and getters
- I am able to do an assignment using this key
- I am able to get the value from the associative array using this key
- Using
declare -p
I am able to save this definition to a file:def.sh
- When sourcing the file
def.sh
an error is emitted.
My Environment
- The version of Bash I'm using is 4.2.46(1)-release (x86_64-redhat-linux-gnu).
- I am on a CentOS 7.3.1611 (Core) server
Workarounds
If instead of doing declare -p array > def.sh
I do instead:
{
echo 'declare -A array'
for Key in "${!array[@]}"; do
EscapedKey="$(sed 's|"|\\"|g' <<<"$Key")"
echo "array[\"$EscapedKey\"]=${array["$Key"]}"
done
} > def.sh
then sourcing the def.sh file works. Note that in the above example, I'm also escaping quote characters that might be a part of the key. I do understand that what I have above is not exhaustive. Because of these complications, I would prefer a solution that doesn't involve such workarounds, if at all possible.
Question
Is there some shopt
,set -o <option>
, or something else I can do to enable me to persist an associative array whose keys may contain square brackets or other special characters to a file and to later be able to source that file successfully? I am needing a solution that works in my environment above.
printf
using%q
. Again, I am hoping for a solution involvingdeclare -p
and perhaps some behavior-changing commands; however, if this turns out to be just a bug in Bash 4.2.26(1)-release, then my goal will turn towards a strong workaround solution, perhaps an improvement on what I've shown above. – VegetarianismCHANGES
. Line 2370: "e. Fixed several bugs encountered when reading subscripts in associative array assignments and expansions. " - this may be it, but usingshopt -s compat42
didn't seem to have any effect in my environment so I'm not sure how to test without compiling bash anew. – Butlerydeclare
wrote the same string to the file except the right-hand value was not in single quotes. Everything else is the same. – Butlerycomplete_fullquote
but it has no effect on this for me. In the changes I found "q. The declare builtin no longer displays array variables using the compound assignment syntax with quotes; that will generate warnings when re-used as input, and isn't necessary. " under the bash 4.3 release notes though. – Butleryupdates
repo. – Vegetarianismsqlite3
, which would let you comfortably store data of this sort and fetch it as well. Depends on what kind of data you have and the scale of course, but for some it might be a far better alternative than working withbash
. – Butlery