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...