3

With the following code:

#! /bin/bash

declare -a arr=("element1"
"element2" "element3" "element4" )
echo "1"
echo "${arr[@]}"

echo "2"
echo ${arr[*]}

The output is:

1
element1 element2 element3 element4
2
element1 element2 element3 element4

So the output is the same.

So when is mandatory use one approach over the other?

Manuel Jordan
  • 1,728
  • 2
  • 16
  • 40

1 Answers1

9

Compare the output of these three loops:

#!/bin/bash

declare -a arr=("this is" "a test" "of bash")

echo "LOOP 1" for x in ${arr[*]}; do echo "item: $x" done echo

echo "LOOP 2" for x in "${arr[*]}"; do echo "item: $x" done echo

echo "LOOP 3" for x in "${arr[@]}"; do echo "item: $x" done

The above script will produce this output:

LOOP 1
item: this
item: is
item: a
item: test
item: of
item: bash

LOOP 2 item: this is a test of bash

LOOP 3 item: this is item: a test item: of bash

The use of "${array[@]}" in double quotes preserves the items in the array, even if they contain whitespace, whereas you lose that information using either "${array[*]}" or ${array[*]}.


This is explained in the "Arrays" section of the bash(1) man page, which says:

Any element of an array may be referenced using ${name[subscript]}. The braces are required to avoid conflicts with pathname expansion. If subscript is @ or *, the word expands to all members of name. These subscripts differ only when the word appears within double quotes. If the word is double-quoted, ${name[*]} expands to a single word with the value of each array member separated by the first character of the IFS special variable, and ${name[@]} expands each element of name to a separate word...

larsks
  • 34,737
  • Practically the difference applies for iteration and not for the direct output as I shared in the original post - should I assume it is the unique difference? – Manuel Jordan Feb 07 '22 at 20:54
  • Consider to add: echo "LOOP 4" for x in ${arr[@]}; do echo "item: $x" done it is such as your Loop 3 but without "" – Manuel Jordan Feb 07 '22 at 21:08
  • 1
    Yeah, I intentionally skipped that because -- per the quoted docs -- it's going to be identical to the LOOP 1 output. – larsks Feb 07 '22 at 21:21
  • 1
    W/r/t to your first quesiton, the difference isn't just in iteration. Compare someprogram "${arr[@]}" vs any other variant of that expression -- the arguments passed to the program will reflect exactly the differences we see in the above loop examples. – larsks Feb 07 '22 at 21:22
  • 2
    @ManuelJordan echo hides the difference. Note that echo "this is a test of bash" and echo "this" "is" "a" "test" "of" "bash" both print exactly the same thing, despite the actual arguments passed to echo being very different (and that difference will matter in almost all situations -- echo is the exception here). – Gordon Davisson Feb 07 '22 at 21:57
  • Thanks for the complementary explanation to you both! – Manuel Jordan Feb 07 '22 at 22:50