Bash Array Pitfalls
Array pitfalls are easy mistakes with quoting, gaps, and empty arrays. Each pitfall changes the result without an error message.
Quoted @ keeps items whole, quoted * joins them
Quoted @ keeps two items whole. Quoted * joins them into one item, so the second loop runs once.
arr=("red apple" "green pear")
echo "items:"
for item in "${arr[@]}"; do
echo "[$item]"
done
echo "joined:"
for item in "${arr[*]}"; do
echo "[$item]"
doneUnset leaves a gap in the indices
Unset removes beta and leaves a gap. The indices skip 1, and the length counts the three items left.
arr=(alpha beta gamma delta)
unset 'arr[1]'
echo "${!arr[@]}"
echo "${#arr[@]}"
echo "${arr[@]}"The empty-array guard under set -u
The guard line prints nothing and the script reaches done. On older Bash the unguarded form could stop a script under set -u, so the guard is the portable form.
set -u
arr=()
echo "before"
echo "${arr[@]:-}"
echo "done"Example
arr=("red apple" "green pear" "blue plum")
unset 'arr[1]'
echo "count: ${#arr[@]}"
echo "indices: ${!arr[@]}"
for item in "${arr[@]}"; do
echo "[$item]"
doneKey points
- Quoted @: "${arr[@]}" keeps each item whole, even items with spaces.
- Quoted *: "${arr[*]}" joins all items into one string.
- Unquoted expansion: an unquoted ${arr[@]} splits items with spaces into separate words.
- Sparse array: unset removes one item and leaves a gap in the indices.
- Sparse length: ${#arr[@]} counts the items left, not the highest index plus one.
- Empty guard: "${arr[@]:-}" expands safely for an empty array, on old and new Bash.
- Old Bash limit: on older Bash, an empty array under set -u could stop a script, so the guard is the portable form.
- Loop guard trap: in a for loop the guard can add one empty item, so use it for plain expansions, not loops.
- Strict Mode: set -u is taught in full in the Strict Mode lesson, later in this course.
In this example, the array holds three fruits with spaces in their names. Unset removes the middle fruit and leaves a gap. The echoes print the count and the gapped indices, and the loop prints the two fruits left, each kept whole.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
Which expansion keeps array items with spaces whole?