This code in Bash

s="There are seven pencil"
declare -A A
while IFS= read -rn1 a; do
 [ -z "$a" ] || [ -n "${A[$a]}" ] && continue
 printf %s "$a"
 ((A[$a]++))    # A[$a]=x
done <<<"$s"

produces this line

Ther a svn pcil

All spaces printed out. Is this behaviour documented or in any other way expected?

Still, when ((A[$a]++)) is replaced with A[$a]=x, the output changes to

Ther asvnpcil

So this time only the first space is printed.

What's the difference?

This is in GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu).

There's a third operation to compare to, namely let "A[$a]=x". Strangely, it falls somewhere in between the former two. It produces the line with all spaces, ie. Ther a svn pcil. But using the reduction from isaac's answer, it behaves like the A[$a]=x assignment:

$ unset A; declare -A A; let "A[' ']++"; declare -p A
declare -A A=([" "]="1" )

Eventually, I've sent a bug report with this. Here's its thread.

1 Answer 1


The core issue is in using arithmetic to declare a variable.


(( A[$a]++ ))


declare -A A["$a"]=1

And the repeated spaces are removed.

It seems to me to be a bug, an space fails to create the variable:

$ declare -A A; (( A[" "]++ )); declare -p A
declare -A A

Addressing your edit after I posted the above answer:

What's the difference?

That an assignment does declare the variable as part of the array:

$ unset A; declare -A A; A[" "]=1 ; declare -p A
declare -A A=([" "]="1" )

while an arithmetic expansion fails to do the equivalent:

$ unset A; declare -A A; (( A[" "]=1 )); declare -p A
declare -A A
  • I agree with the difference, and I agree that it looks like a bug. I have one more reference: declare -A A; let "A[' ']++"; declare -p A gives declare -A A=([" "]="1" ).
    – user147505
    Commented Jan 25, 2018 at 1:39
  • I have doubts about the syntax in this line of your answer: declare -A A["$a"]=1. It looks to me like declaring another associative array. Simple declare A["$a"]=1 makes the change too.
    – user147505
    Commented Jan 25, 2018 at 1:48
  • @tomasz Both syntaxes are valid and equivalent. No it is not declaring a new variable, the name is still A for both declarations.
    – user232326
    Commented Jan 25, 2018 at 1:51
  • Strangely, let "A[$a]=x" produces all spaces in the original context. (I updated my question.)
    – user147505
    Commented Jan 25, 2018 at 2:05
  • 1
    Testing with unset A; a=" ";declare -A A; let "A[$a]=x"; declare -p A still fails to create the variable, thus all spaces is the expected result. @tomasz
    – user232326
    Commented Jan 25, 2018 at 2:19

You must log in to answer this question.