Date: Wed, 9 Jul 2025 14:00:46 -0400 From: Greg Wooledge <g...@wooledge.org> Message-ID: <20250709180045.ga28...@wooledge.org>
| If that's true, then I don't understand why these two commands give | different results: | | (( hash[\$key]++ )) | let "hash[\$key]++" | | hobbit:~$ echo "$BASH_VERSION" | 5.3.0(1)-release | hobbit:~$ unset hash | hobbit:~$ declare -A hash; key=\'\] | hobbit:~$ (( hash[\$key]++ )); declare -p hash | declare -A hash=(["\$key"]="1" ) | hobbit:~$ let "hash[\$key]++"; declare -p hash | declare -A hash=(["\$key"]="1" ["']"]="1" ) Partly that is because the start conditions aren't the same, for the (( )) test "hash" is unset, but declared to be an assoc array. For the let test, hash is already set. But only partly... jacaranda$ echo "$BASH_VERSION" 5.3.0(1)-release jacaranda$ unset hash jacaranda$ declare -A hash; key=\'\] jacaranda$ let "hash[\$key]++"; declare -p hash declare -A hash=(["']"]="1" ) So it is still different, just different different. And for this, the (( )) version is clearly correct, the '\' that is inserted before the $ in a string which is (as Chet said) treated as double quoted, prevents the '$key' from being a variable reference, and instead makes it be just the 4 characters '$' 'k' 'e' 'y' (and in which "declare -p" needs to similarly escape the '$' for correctness). jacaranda$ unset hash jacaranda$ declare -A hash; key=\'\] jacaranda$ (( hash[$key]++ )); declare -p hash declare -A hash=(["']"]="1" ) which also looks correct to me (not that I really know, or care, about associative arrays, or any arrays, in sh programming - poor addition to the shell IMO (lists would be better)). Why let isn't producing the same result I will leave it to Chet to explain, its arg is explicitly double quoted, the \$ in there should mean the same as it does in the (( )) version. kre