When you are counting the number of elements (using the # symbol), there is no difference between ${#NAMES[*]} and ${#NAMES[@]}. Both will return the total number of elements in the array.
However, when you are accessing the actual content of the array (without the #), the difference is very important, especially when it comes to spaces in names.
1. The Key Difference: Quoting
The difference only appears when you wrap the expression in double quotes.
-
"${NAMES[@]}"(The Recommended Way):
Expands each element as a separate quoted string. If you have a name like "John Doe", Bash sees it as one single item.- Think of it as:
"John""Eric""Jessica"
- Think of it as:
-
"${NAMES[*]}":
Expands all elements into a single string, separated by the first character of theIFSvariable (usually a space).- Think of it as:
"John Eric Jessica"
- Think of it as:
2. Why does this matter?
Imagine you have an array with a name containing a space:
NAMES=("John Doe" "Eric")
If you use a for loop:
# Using SECOND option (@)
for name in "${NAMES[@]}"; do
echo "Hello $name"
done
# Result:
# Hello John Doe
# Hello Eric
# Using FIRST option (*)
for name in "${NAMES[*]}"; do
echo "Hello $name"
done
# Result:
# Hello John Doe Eric
Summary for your Lab
- For Counting:
${#NAMES[@]}and${#NAMES[*]}are identical. Both give you the number of elements. - For Accessing Data: Always prefer
"${NAMES[@]}"(with quotes and the@symbol). It is much safer because it preserves elements exactly as they were entered, even if they contain spaces.
In short: @ is for "At" each element individually; * is for "All" elements as one big lump.