A condensed, practical Bash reference for day-to-day scripting. Bash-specific where noted.

Quotes & Substitution

Pattern Meaning Example → Result
'text' literal, no expansion '$HOME'$HOME
"text" expand vars & commands, preserve spaces "hi $USER"
$(cmd) run command, capture output $(pwd)
$'text' C-style escapes $'\n' → newline

Pipes & Redirection

Pattern Meaning Example
cmd1 | cmd2 pipe stdout ls | wc -l
cmd1 |& cmd2 pipe stdout+stderr (Bash) make |& tee log
> stdout → file (overwrite) echo hi > x
>> stdout → file (append) echo hi >> x
< stdin ← file wc -l < x
2> stderr → file cmd 2> err
&> stdout+stderr → file (Bash) cmd &> all.log
2>&1 stderr → stdout cmd 2>&1
<<< "s" here-string (Bash) grep hi <<< "$t"
<<EOF heredoc cat <<EOF

Process Substitution (Bash)

Pattern Meaning Example
<(cmd) pretend-file (output) diff <(sort a) <(sort b)
>(cmd) send input echo hi > >(sed 's/h/H/')

Parameter Expansion

Pattern Meaning Example
${v:-x} default if unset or empty ${a:-hi}
${v-x} default if unset ${a-hi}
${v:=x} assign default if unset or empty ${a:=hi}
${v:?msg} error if unset or empty ${a:?nope}
${v:+x} x if set and non-empty ${a:+yes}
${v#p} / ${v##p} trim front (short/long) ${p##*/}
${v%p} / ${v%%p} trim back (short/long) ${f%%.*}
${v/p/r} replace first ${x/-/_}
${v//p/r} replace all ${x//-/_}
${#v} length ${#s}
${v:pos} substring ${s:2}
${v:pos:len} substring (bounded) ${s:1:3}

Globs & Brace Expansion

Pattern Meaning Example
* anything *.txt
? one char a?.txt
[abc] char class file[1-9]
{a,b} alternation (brace expansion) {dev,prod}.cfg
{1..5} sequence {1..3}

Variables & Environment

Pattern Meaning Example
v=hi assign name="tien"
export v expose to child processes export PATH
readonly v make constant readonly API_KEY
local v=x function-local (Bash) inside functions
$? last exit code echo $?

IFS — Internal Field Separator

Variable / Pattern Meaning Example / Notes
IFS controls word-splitting default: space, tab, newline
IFS=$'\n' split only on newline safer for filenames with spaces
IFS=: split on colon useful for parsing $PATH
IFS= read -r line prevent word splitting safest line reader

Common Internal Variables

Variable Meaning Example
$0 script name echo "$0"
$1..$9 positional args $1 = first arg
$# number of args echo "$#"
"$@" all args (safe) for a in "$@"; do ...; done
$* all args (unsafe) expands as one string
$$ PID of the script useful for temp files
$! PID of last background job cmd &; echo $!
$? exit code of last command echo $?
$- current shell flags shows states like himBH
$_ last argument of previous command REPL convenience
$PWD current directory same as pwd
$OLDPWD previous directory used by cd -
$RANDOM random int 0–32767 (Bash) echo $RANDOM
$LINENO current line in script debugging
${BASH_SOURCE[0]} script filename (Bash) more reliable than $0
$FUNCNAME function call stack (Bash) ${FUNCNAME[0]} = current

Functions

Pattern Meaning Example
f() { cmds; } standard form f(){ echo ok; }
function f {} alternative (Bash) non-POSIX
$1 $2 "$@" arguments echo "$1"
return n function exit code return 42

Blocks & Subshells

Pattern Meaning Example
( cmds ) subshell (cd /; pwd)
{ cmds; } group (same shell) { cd /; pwd; }

Conditionals & Comparisons

if / elif / else

if [[ $x -gt 10 ]]; then
  echo big
elif [[ $x -gt 5 ]]; then
  echo medium
else
  echo small
fi

case (preferred over long if-chains)

case "$cmd" in
  start) echo "Starting" ;;
  stop)  echo "Stopping" ;;
  *)     echo "Unknown" ;;
esac

[[ ... ]] vs [ ... ]

Form Use Notes
[[ ... ]] Bash test safer; supports pattern matching and regex
[ ... ] POSIX test works in /bin/sh; requires careful quoting

Examples:

[[ "$a" == "$b" ]]
[ -f "$file" ]

Boolean chaining

cmd && echo success
cmd || echo failed

Comparison Operators (Strings vs Numbers)

Numeric Comparisons (preferred: arithmetic context)

Operator Meaning
-eq / == equal
-ne / != not equal
-gt / > greater than
-lt / < less than
-ge / >= greater or equal
-le / <= less or equal

Examples:

(( a > b ))
(( a >= 10 ))

POSIX form:

[ "$a" -gt "$b" ]

String Comparisons

Operator Meaning
== equal
!= not equal
< lexicographically less
> lexicographically greater
-z empty string
-n non-empty string

Examples:

[[ "$a" == "$b" ]]
[[ -z "$s" ]]

Notes

  • Prefer (( )) for numbers
  • Prefer [[ ]] for strings
  • < and > must be escaped in [ ] but not in [[ ]]

File & String Tests (inside [ ] or [[ ]])

Pattern Meaning
-f regular file
-d directory
-e exists
-s size > 0
-r -w -x readable/writeable/executable
-n non-empty string
-z empty string

Usage:

[[ -f "$path" ]] && echo yes

Loops

Pattern Meaning Example
for x in ... list iteration for f in *.txt; do echo "$f"; done
while cmd loop while cmd succeeds while read -r l; do ...; done < file
until cmd loop until cmd succeeds until ping -c1 host; do :; done
break / continue flow control

Safe Line Reading

while IFS= read -r line; do
  echo "$line"
done < file.txt

Arithmetic

Pattern Meaning
((i++)) increment
((i+=2)) add
x=$((a+b)) compute

Job Control (Interactive Bash)

Pattern Meaning
cmd & run in background
jobs list jobs
fg %1 bring to foreground
bg %1 resume in background
Ctrl-Z suspend
Ctrl-C interrupt

Exit Handling & Traps

Pattern Meaning
trap 'cmd' EXIT run on script exit
trap 'cmd' ERR run when a command errors
trap - ERR clear trap

Example (propagate ERR trap into functions):

set -E
trap 'echo "error at line $LINENO"' ERR
set -euo pipefail

Script Safety Flags

set -euo pipefail

Note: -e has edge cases; pairing it with an ERR trap makes failures easier to diagnose.