Variables & quoting
Store values, interpolate them, and — most importantly — quote them to survive spaces, globs, and special characters.
Word splitting is what makes unquoted variables dangerous. After expansion, Bash splits the result on characters in $IFS (default: space, tab, newline), then runs pathname expansion on each word. rm $file → expand → split → glob → hand off to rm. Quoting suppresses splitting and globbing, keeping the value as a single argument.
Parameter expansion: Bash has a rich set of ${...} operators. ${var:-default} (use default if unset/empty), ${var:=default} (also assign), ${var:?message} (abort with message if unset), ${#var} (length), ${var#prefix} / ${var##prefix} (strip shortest/longest prefix), ${var%suffix} / ${var%%suffix} (strip suffix), ${var/old/new} (replace first), ${var//old/new} (replace all), ${var,,} / ${var^^} (lower/upper case, Bash 4+).
$@ vs $*: both list all positional parameters. Inside double quotes, "$@" expands to "$1" "$2" ... (each arg preserved as a separate word — the safe way to forward arguments). "$*" expands to "$1 $2 ..." (single string joined by the first char of $IFS). Rule: always use "$@" to pass args through.
Export vs local scope: plain VAR=x sets a shell variable — visible to this shell and its functions only. export VAR=x promotes it to an environment variable — inherited by child processes. local var=x (inside a function) scopes to the function. Forgetting export is why VAR=x node script.js does not show VAR in process.env unless you also use VAR=x cmd inline syntax, which DOES export for that one command.
Arrays (Bash 3+): indexed arrays arr=(a b c), access ${arr[0]}, all elements "${arr[@]}", length ${#arr[@]}. Associative arrays (Bash 4+): declare -A map; map[key]=value; echo "${map[key]}". Iteration pattern: for item in "${arr[@]}"; do ...; done (quoting is critical; unquoted loses items with spaces).
Quoting rules for safety: run ShellCheck on every non-trivial script. It flags unquoted variables, useless cats, [[ misuse, and countless other footguns. 'Works on my machine' scripts usually have silent quoting bugs that appear when a filename contains a space or a variable goes unexpectedly empty.
Grounded on https://www.gnu.org/software/bash/manual/bash.html#Shell-Parameter-Expansion
Next up
Control flow — if, for, while, case
Branch on exit codes, loop over lists or streams, match patterns. Bash control flow is quirky — exit code 0 means true.