Build the mental model
In bash you assign a variable with `name=value` — no spaces are allowed around the `=`, because bash would otherwise try to parse `name` as a command and `=value` as its argument — and you read it back with `$name` or the more explicit `${name}`, which is necessary whenever the variable name butts up against other characters (like `${name}_backup`) that bash could otherwise fold into the identifier. How you quote that reference changes its behavior enormously. Single quotes treat everything inside them as completely literal text, with no variable expansion, no command substitution, and no escape sequences recognized at all — they're the safest choice when you genuinely want text preserved exactly as typed. Double quotes still expand variables and command substitutions but keep the combined result as a single word, protecting embedded spaces from being split apart. Leaving a variable unquoted is the dangerous default: bash expands it first, then runs word splitting (breaking the result apart on whitespace) and filename globbing (expanding patterns like `*`) on whatever comes out, which can silently turn one value into several separate arguments or make bash try to match files that were never intended. Command substitution with `$(command)` captures a command's standard output into a variable — trimming trailing newlines in the process — and once that output is stored in a variable, it's subject to the exact same quoting rules as any other variable when you use it again.
Connect it to a real scenario
A script that processes file paths is the classic place this bites people: a path like `/home/user/My Documents/report.pdf` has a space in it, and if you write `rm $filepath` instead of `rm "$filepath"`, bash first expands `$filepath` and then, because it's unquoted, splits the result on whitespace into two separate arguments — `/home/user/My` and `Documents/report.pdf` — neither of which is the file you meant, so `rm` either fails with 'no such file' or, worse, deletes something you didn't intend. The lesson's own example demonstrates this directly: looping over `$path` unquoted breaks `/tmp/my folder/file.txt` into two words, while looping over `"$path"` keeps it as one. Getting into the habit of double-quoting every variable reference by default, and reaching for single quotes only when you deliberately want literal text, avoids this entire class of bug before it ever has a chance to happen.
Try the working example
#!/usr/bin/env bash
name="Bash Learner"
single_quoted='Hello, $name!' # single quotes: fully literal, no expansion
double_quoted="Hello, $name!" # double quotes: variables expand
shout=$(echo "hello there" | tr 'a-z' 'A-Z') # command substitution
echo "Single-quoted: $single_quoted"
echo "Double-quoted: $double_quoted"
echo "Command substitution: $shout"
path="/tmp/my folder/file.txt"
echo "Unquoted (word splitting):"
for word in $path; do
echo " word -> $word"
done
echo "Quoted (no splitting):"
for word in "$path"; do
echo " word -> $word"
doneRunning this script prints:
Single-quoted: Hello, $name!
Double-quoted: Hello, Bash Learner!
Command substitution: HELLO THERE
Unquoted (word splitting):
word -> /tmp/my
word -> folder/file.txt
Quoted (no splitting):
word -> /tmp/my folder/file.txt5-minute try-it
Create a variable holding a path with a space in it, like `project_dir="my project/src"`, then write a loop that lists the pieces both with and without quotes around `$project_dir` and observe how the results differ.
One important caution
Forgetting to quote a variable that might contain spaces, causing bash to word-split it into multiple arguments (e.g. rm $filepath deleting or referencing the wrong things)
Assuming single quotes work like double quotes and being surprised when 'Hello, $name!' prints literally instead of substituting the value
GNU Bash Reference Manual — Quoting — Bash / Shell Scripting