← Back to Bash Course | Chapter 14: Best Practices & Real-World Scripting | Lesson 1 of 7

Quoting Pitfalls and Why to Always Quote Variables

Putting quotation marks around a variable in Bash protects its value from being accidentally split into pieces or treated as a wildcard pattern.

Word Splitting on Unquoted Variables

When a variable containing spaces is used unquoted, bash splits it into multiple separate words on IFS before passing them to a command, which usually is not what was intended.

Example: Word Splitting on Unquoted Variables

bash
#!/bin/bash
count_args() { echo "received $# argument(s)"; }

phrase="hello there world"
count_args $phrase
count_args "$phrase"

Accidental Globbing

An unquoted variable whose value contains glob characters like * gets expanded against real filenames in the current directory, which can silently turn one literal string into a list of unrelated filenames.

Example: Accidental Globbing

bash
#!/bin/bash
touch star_demo_a.txt star_demo_b.txt
pattern="star_demo_*.txt"
echo "unquoted (expands against real files): $pattern"
echo unquoted: $pattern
echo "quoted (kept literal): \"$pattern\""
rm -f star_demo_a.txt star_demo_b.txt

Disappearing Empty Variables

An unquoted empty (or unset) variable expands to nothing at all, effectively vanishing from the command line, which can shift what the next real argument is interpreted as. Quoting keeps it as a genuine empty-string argument.

Example: Disappearing Empty Variables

bash
#!/bin/bash
show_args() {
    echo "count: $#"
    for a in "$@"; do echo "[${a}]"; done
}

empty_var=""
show_args $empty_var second
echo "---"
show_args "$empty_var" second

A Safe Default Habit

Quoting every variable expansion by default, and only deliberately leaving one unquoted when word splitting or globbing is actually wanted, avoids an entire category of subtle bugs.

Note: Tools like shellcheck flag most unquoted-variable mistakes automatically and are worth running on any real script.

Example: A Safe Default Habit

bash
#!/bin/bash
filename="my report.txt"
touch "$filename"
if [[ -f "$filename" ]]; then
    echo "file with a space in its name handled correctly"
fi
rm -f "$filename"
Common Mistakes
  1. Leaving a variable unquoted and assuming it will always be treated as one value, when Bash actually word-splits it on whitespace first.
  2. Forgetting an unquoted variable containing * or ? gets glob-expanded against real filenames in the current directory.
  3. Believing quoting is only needed for values that "might have spaces"; an empty unquoted variable can also vanish entirely and shift argument positions.
Chapter Summary
  • Unquoted variable expansions undergo word splitting (on IFS) and filename globbing before the command runs.
  • "$var" prevents both word splitting and globbing, preserving the variable's exact value as one argument.
  • An unquoted empty variable disappears completely rather than becoming an empty argument, which can shift positional arguments unexpectedly.
  • As a default habit, quote every variable expansion unless you specifically want word splitting or globbing to happen.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.