Lesson 1 of 6
Variables & Quoting
Master single vs double quotes, kill word-splitting bugs, and wield parameter expansion — defaults (${x:-}), required-checks (${x:?}), substrings, pattern stripping, and arrays that keep their elements intact.
① Watch
Speed
📖 Read this walkthrough — every command, and why
Variables & Quoting — hold text, expand it safely
Mental model: a variable just holds text. You assign with name=value (no spaces around =),
and you read it back with $name — the shell expands it into the command line BEFORE the command runs.
The one rule that saves you from most shell bugs: ALWAYS quote your expansions -> "$var".
1 · Assign and expand
name="Ada Lovelace" # no spaces around '=' ; quote values with spaces
echo "$name" # -> Ada Lovelace
2 · Why you must quote — the #1 gotcha
When the shell expands an UNQUOTED $name, it doesn't hand back one value.
It first word-splits the result on whitespace (IFS), then glob-expands wildcards.
So with name="Ada Lovelace":
unquoted $name word-splits into two args: [Ada] [Lovelace]
quoted "$name" is one value: [Ada Lovelace]
Unquoted, the command sees two arguments (Ada, Lovelace) as if you typed two things.
Quoted, it receives one argument, exactly the value you stored. Same trap bites filenames
with spaces: ls $f looks for two files; ls "$f" looks for the one you meant.
3 · Parameter expansions — more than the plain value
${var:-default} substitute a fallback when var is empty or unset (does NOT assign var)
echo "${missing:-fallback}" -> fallback
${#var} length of the value, in characters (handy to validate input)
name="Ada Lovelace"; echo "${#name}" -> 12
${var//a/b} replace ALL occurrences of a with b (single '/' replaces only the first)
s="banana"; echo "${s//a/o}" -> bonono
4 · Command substitution and arithmetic
$( ... ) run a command and drop its stdout into the line
today="$(date +%F)"; echo "$today"
$(( ... )) integer arithmetic; no '$' needed on names inside
n=6; echo "$(( n * 7 ))" -> 42
Notes / gotchas
- No spaces around '=' in assignment: name=Ada (not name = Ada).
- Double quotes "$var" allow expansion but stop word-splitting and globbing — the safe default.
- Single quotes '$var' are fully literal: no expansion at all (prints $var verbatim).
- ${var:-x} substitutes but does NOT set var; use ${var:=x} if you also want to assign it.
- Always quote expansions unless you specifically want splitting or globbing.
Verify:
name="Ada Lovelace"
printf '[%s]' $name; echo # unquoted -> [Ada][Lovelace] (two args)
printf '[%s]' "$name"; echo # quoted -> [Ada Lovelace] (one arg)
n=6; echo "$(( n * 7 ))" # -> 42