Cheat sheet · No. VII
Shell.
The shell is a text-pipeline engine. Master parameter expansion, the three standard streams, and exit codes, and most scripting stops being guesswork.
The reference
PARAMETER EXPANSION
${name}- Value
${name:-d}- Default if unset/empty
${name:=d}- Assign default
${name:?msg}- Error if unset
${#name}- Length
${name#prefix}- Strip prefix (shortest)
${name##prefix}- Strip prefix (longest)
${name%suffix}- Strip suffix (shortest)
${name/old/new}- Substitute first
REDIRECTION
> file- stdout to file (truncate)
>> file- Append
2> file- stderr to file
> file 2>&1- Both to file (order matters!)
&> file- Same, bash shorthand
< file- stdin from file
<<EOF- Heredoc
<<< "string"- Here-string
SIGNALS
SIGHUP (1)- Terminal closed; reload
SIGINT (2)- Ctrl-C
SIGQUIT (3)- Ctrl-\ + core dump
SIGKILL (9)- Force-kill, uncatchable
SIGTERM (15)- Default kill, catchable
SIGSTOP (19)- Pause, uncatchable
SIGCONT (18)- Resume
SIGUSR1 (10)- App-defined
EXIT CODES
0- Success
1- Generic failure
2- Misuse of shell builtin
126- Cannot execute
127- Command not found
128 + N- Killed by signal N
$?- Exit code of last command
PIPING & CHAINS
a | b- Pipe stdout to stdin
a |& b- Pipe stdout + stderr
a && b- Run b only if a succeeds
a || b- Run b only if a fails
a ; b- Run b after a regardless
$(cmd)- Command substitution
<(cmd)- Process substitution → file
GLOBS
*- Anything (no /)
**- Anything, recursive (with globstar)
?- One char
[abc][!abc]- Char class
{a,b,c}- Brace expansion (literal, not glob)
Field notes
Always quote expansions
Write "$var", not $var. Unquoted, the shell splits on whitespace and globs — the root of most "works on my machine" bugs.
Redirection order matters
> file 2>&1 sends both streams to the file; 2>&1 > file does not — stderr still goes to the terminal because it is bound first.
Chains read exit status
cmd && next runs next only on success (exit 0); cmd || fallback runs only on failure. Combine them for terse guards.
Default vs assign-default
${var:-x} substitutes a fallback without changing var; ${var:=x} also assigns it. A tiny difference with big consequences.