🎓 A1Learner
🔍
0 of 46 lessons completed

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]"
done

Unset 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]"
done

Key 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?