I want an associative array in my bashrc file and I want to add to or delete from it whenever needed, but if I put the array declaration in the bashrc file it will get redeclared every time bash is run and so the previous values will be lost. What should I do?
1 Answer
I don't think there's any nice way to do that. You'll have to do the de/serialization, saving and restoring by hand. Example code:
save_array(){
declare -n a=$1
for i in "${!a[@]}"; do printf '%s\0%s\0' "$i" "${a[$i]}"; done
}
restore_array(){
unset $1; declare -gA $1
declare -n a=$1; local k v
while read -d '' k && read -d '' v; do a[$k]=$v; done
}
Or a simpler variant, which takes advantage of the format of declare -p[1]:
save_array(){ declare -p $1; }
restore_array(){ local l; read -r l; eval "${l/-A*=(/-gA $1=(}"; }
Then:
$ declare -A a1; a1[foo]=bar; a1[baz]=qux
$ save_array a1 >/tmp/save
$ restore_array a2 </tmp/save
$ echo "${!a2[@]} // ${a2[@]}"
baz foo // qux bar
The readarray/mapfile built-in doesn't seem to support associative arrays, nor using NUL bytes as delimiters. Also, bash doesn't seem able to tie an array to a database, as perl can with tie %hash, 'DB_File', $filename, ....
[1] depending on your usage, you can make it even simpler:
#! /bin/bash
trap 'declare -p a1 a2 > ./path/to/saved_arrays' EXIT
. ./path/to/saved_arrays 2>/dev/null || declare -A a1 a2
a1[$1]=$2
a2[$2]=$1
-
I've hit on a much better idea, see the updated answer.user313992– user3139922019-05-12 06:53:23 +00:00Commented May 12, 2019 at 6:53
-
I'm just learning these commands, but it's strange "EXIT" was not in the "man 7 signal" and was in the "man trap" instead. The second way sounds amazing. "delcare -p array" is interesting. BTW, what's this doing
2>/dev/nullin the second solution?aderchox– aderchox2019-05-12 08:31:54 +00:00Commented May 12, 2019 at 8:31 -
Oh Google found that easily and I read what it does. thanks again.aderchox– aderchox2019-05-12 08:40:17 +00:00Commented May 12, 2019 at 8:40
[ -z ${var+x} ].