When I execute the following code, the output of the printf statement appears to show array out of sequence. In the declare statement the Source item is declared before Destination and in the output it's reversed.

declare -A OP=( [Description]="remote to destination" [Source]="/var/www" [Destination]="/foo/bar" [Log]="my.log" [Email]="me@here" );

NO_COLS=`tput cols`

for i in "${!OP[@]}"; do
    printf $PRINT_FORMAT "$i :" " $YELLOW${OP[$i]}$ENDCOL"
done ;

Output looks like

         Description : remote to destination
         Destination : /foo/bar
              Source : /var/www
                 Log : my.log
               Email : me@here

Can anyone tell me what is happening here? or how I can achieve the proper order according to the array declaration?

  • 3
    Associative arrays have no inherent order. The insertion order is not preserved. Jan 28, 2015 at 3:58
  • That makes sense, although it appears to obey some type of order because it consistently prints the same sequence even if you move the variables around in the declaration. It just so happened that I declared them similar to the output which is why I thought there was something wrong with the code. Problem solved with the answer here... just curious.
    – dimmech
    Jan 28, 2015 at 14:05

1 Answer 1


Associative array in bash (and in other languages) does not preserve the order of elements in declaration.

You can add another associative array to keep track the order of declaration:

declare -A OP=( [Description]="remote to destination"
                [Email]="me@here" )

declare -A IP=( [1]="Description"
                [5]="Email" );

NO_COLS="$(tput cols)"

for i in "${!IP[@]}"; do
  printf "$PRINT_FORMAT" "$k :" " $YELLOW${OP[$k]}$ENDCOL"

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .