Portal | Level: L0: Entry | Topics: Bash / Shell Scripting | Domain: Linux
Bash - Skill Check¶
Mental model (bottom-up)¶
Bash takes text and does parsing + expansions + word splitting + globbing, then execs programs. Most Bash bugs are: unquoted expansions, IFS/whitespace, or subshell scope.
Visual stack¶
[Script text ] what you typed
|
[Parser ] builds commands/words/redirects
|
[Expansions ] vars, command subst, arithmetic, globs
|
[Word splitting ] IFS splits unquoted expansions into multiple args
|
[Exec ] runs builtins or forks external commands
Glossary¶
- word splitting - turning one string into multiple args on whitespace/IFS
- globbing - expanding * ? [] patterns into filenames
- subshell - child shell; variable changes don't persist to parent
- pipeline - cmd1 | cmd2 (stdout of left becomes stdin of right)
- here-doc - multiline input redirected into a command (<<EOF)
- trap - run cleanup code on signals/exit
- exit code - 0 success; nonzero means failure
Expansion order (why quoting matters)¶
Common failure modes¶
for f in $(find ...)explodes on whitespace/newlines.- Missing
pipefailhides errors in pipelines. - Using
echofor data (it lies); preferprintf.
Roadmap core (10, easy -> hard)¶
- Single quotes vs double quotes?
'...'no expansion;"..."expands variables/escapes."$@"vs"$*"?"$@"preserves args;"$*"joins into one string.- What does
set -euo pipefaildo? - Exit on error/unset var; fail pipelines if any command fails.
- Safely loop over filenames with spaces?
while IFS= read -r -d '' f; do ...; done < <(find ... -print0)- stdout+stderr to file?
cmd >out 2>&1(orcmd &>out)- stderr only to file?
cmd 2>err- Strip suffix
.logfrom var? ${x%.log}- Default if unset/empty?
${x:-default}- Trap cleanup on exit?
trap 'rm -f "$tmp"' EXIT- Why pipelines hide failures + fix?
- Exit code is last command; use
pipefailor inspect${PIPESTATUS[@]}.
Quoting & expansions (easy -> hard)¶
- What's word-splitting?
- Unquoted expansion splits on IFS; surprise extra args.
- Why prefer
"${var}"over$var? - Prevents globbing/splitting; preserves empty values.
${var:=default}vs${var:-default}?:=assigns if unset/empty;:-substitutes only.- What does
${var%/*}do? - Strip shortest suffix matching
/*(dirname-ish). - What is globbing and how to disable?
* ? []pattern expansion;set -fdisables.[[ ... ]]vs[ ... ]?[[avoids word-splitting/globbing in many cases and supports regex.
Control flow & data (easy -> hard)¶
- Why
casebeatsifchains? - Cleaner matching; less quoting pain.
- Arrays: append and iterate safely?
a+=("$x");for x in "${a[@]}"; do ...; done- Why
read -r? - Prevents backslash escapes from being interpreted.
- What does
IFS=inreaddo? - Prevents trimming leading/trailing whitespace.
- Process substitution
< <(...)vs pipe|? - Keeps loop in current shell (often) and preserves variables.
- When to avoid
for f in $(...)? - Breaks on whitespace/newlines; use
find -print0+read -d ''.
Defensive Bash (easy -> hard)¶
- Why
set -ucan bite you? - Unset vars abort; guard with
${var-}or defaults. - How to fail with a useful message?
die(){ echo "ERR: $*" >&2; exit 1; }- How to validate args fast?
- Check count, types, file exists/readable/writable;
[[ -f ... ]]. - Why use
mktemp? - Avoid predictable temp names; prevent races/attacks.
- How to prevent partial writes?
- Write to temp,
mvatomic replace. - Why
shellcheckmatters? - Catches quoting bugs and common footguns.
Text processing boundaries (easy -> hard)¶
- When to use
grep/sed/awkvs pure Bash? - Use tools for streaming transforms; keep Bash for orchestration.
- Why
LC_ALL=Csometimes? - Deterministic byte-wise ordering and faster collation.
- How to handle NUL-delimited streams?
-print0+xargs -0/read -d ''.- What is "UUOC" and why care?
- "Useless use of cat"; avoid extra processes in hot paths.
- What does "avoid subshell" mean?
- Some pipelines spawn subshell; variables won't persist.
Performance patterns (easy -> hard)¶
- What kills Bash performance?
- Per-line forks; heavy subshells;
$(...)in tight loops. - Batch external calls how?
- Use
xargs -0 -nor aggregate into fewer invocations. - Why prefer builtins (
printf) overecho? - Predictable behavior; fewer portability surprises.
- When do you switch to Python?
- Complex parsing, data structures, concurrency, tests.
Visual guides¶
Sources¶
- GNU Bash Reference Manual; POSIX shell docs.
- https://www.gnu.org/software/bash/manual/
Wiki Navigation¶
Related Content¶
- Advanced Bash for Ops (Topic Pack, L1) — Bash / Shell Scripting
- Bash Exercises (Quest Ladder) (CLI) (Exercise Set, L0) — Bash / Shell Scripting
- Bash Flashcards (CLI) (flashcard_deck, L1) — Bash / Shell Scripting
- Cron & Job Scheduling (Topic Pack, L1) — Bash / Shell Scripting
- Environment Variables (Topic Pack, L1) — Bash / Shell Scripting
- Fleet Operations at Scale (Topic Pack, L2) — Bash / Shell Scripting
- LPIC / LFCS Exam Preparation (Topic Pack, L2) — Bash / Shell Scripting
- Linux Ops (Topic Pack, L0) — Bash / Shell Scripting
- Linux Ops Drills (Drill, L0) — Bash / Shell Scripting
- Linux Text Processing (Topic Pack, L1) — Bash / Shell Scripting