Quoting: Double, Single, None
A student renames her folder to My Notes, runs backup.sh, and tar replies that /home/asha/My and Notes do not exist. The script did not change; the data did. Quoting is how you tell Bash where one piece of text ends, and it is the single biggest source of shell bugs.
The rule
Double quotes keep
$alive; single quotes keep everything literal.
In Bash, every value is a string. What changes is how Bash treats the text on the way into a command:
| Written as | Variables expand? | Split on spaces? | * matches files? |
|---|---|---|---|
$src |
yes | yes | yes |
"$src" |
yes | no | no |
'$src' |
no | no | no |
src="$HOME/My Notes"
echo '$src' # prints: $src
echo "$src" # prints: /home/asha/My Notes
ls $src # ls receives two arguments: /home/asha/My and Notes
ls "$src" # ls receives one argument, space includedInside double quotes, a few characters stay special: $, backquote, and \. Write \$ for a literal dollar and \" for a literal double quote. Inside single quotes nothing is special, not even the backslash, so a single quote cannot appear inside single quotes at all. For text like It's done, use double quotes.
The shortcut
Put double quotes around every $, by default. Only drop them when you truly want splitting (rare), and switch to single quotes when you want zero expansion.
The line
tar -czf "$archive" $srcwithsrc="/home/asha/My Notes".
Unquoted values are also treated as file patterns. If a variable holds *, then echo $x prints the names of the files in the current folder, not a star.
Drills
Answer fast — trust the rule.
What does echo '$HOME' print?
After f="a b", how many lines does printf '%s\n' $f print?
What does echo "Cost: \$5" print?
In a folder holding only a.txt and b.txt, what does x='*'; echo $x print?
Which command prints It's done?
Remember
- Double quotes keep
$alive; single quotes keep everything literal. - Default to
"$var"around every expansion. - Trap: unquoted values split on spaces and expand
*into file names.
