ssprkd.io
Shell Scripting
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