The essentials

Quick reference

One focused task per row. Jump to the related section for complete, working examples.

UseSyntaxExamples
Select Bash through PATH#!/usr/bin/env bashView examples
Enable stricter failure handlingset -Eeuo pipefailView examples
Read an argumentinput=${1:?usage: script INPUT}View examples
Supply a defaultmode=${MODE:-safe}View examples
Preserve one argumentprintf '%s\n' "$filename"View examples
Create an arrayfiles=("report one.txt" "report two.txt")View examples
Pass every array membercommand -- "${files[@]}"View examples
Read a literal lineIFS= read -r lineView examples
Process a file line by linewhile IFS= read -r line; do printf '%s\n' "$line"; done \ < input.txtView examples
Test a regular fileif [[ -f $path ]]; then process "$path"; fiView examples
Compare integersif (( count > 10 )); then printf 'large\n'; fiView examples
Match alternativescase $mode in safe|fast) run "$mode" ;; *) exit 2 ;; \ esacView examples
Define a functionlog() { printf '%s\n' "$*" >&2; }View examples
Keep function state locallocal path=$1View examples
Parse short optionswhile getopts ':o:v' option; do case $option in o) \ output=$OPTARG ;; v) verbose=1 ;; esac; doneView examples
Remove parsed optionsshift "$((OPTIND - 1))"View examples
Create a temporary directoryworkdir=$(mktemp -d)View examples
Clean up on exittrap 'rm -rf -- "$workdir"' EXITView examples
Check syntaxbash -n script.shView examples
Run static analysisshellcheck script.shView examples

Bash is effective for orchestrating commands and files, but its expansion and error rules demand precision. Quote expansions, keep data in arrays, validate arguments before changing state, and make cleanup explicit. Move to a general-purpose language when data structures or error recovery dominate the script.

Step by step

Detailed examples

01

Declare the interpreter and error policy

A shebang affects direct execution but not `bash script.sh`. env follows PATH, which is convenient across systems but may select an unintended interpreter in privileged or tightly controlled contexts. `set -Eeuo pipefail` catches many failures, yet errexit has context-dependent exceptions and is not a substitute for checking expected failures explicitly.

A guarded script entry
#!/usr/bin/env bash
set -Eeuo pipefail

printf 'bash version: %s\n' "$BASH_VERSION"
Back to quick reference ↑
02

Validate arguments and quote expansions

Parameter expansion can reject missing inputs or provide defaults before commands run. Double-quote variable and command substitutions unless splitting or globbing is specifically intended. Use `--` where a command supports it so a filename beginning with a dash is not parsed as an option.

Require an input and preserve its exact spelling
#!/usr/bin/env bash
set -Eeuo pipefail

input=${1:?usage: inspect.sh INPUT}
mode=${MODE:-safe}
printf 'input=%s mode=%s\n' "$input" "$mode"
Back to quick reference ↑
03

Keep lists as arrays and lines as lines

A space-delimited string cannot reliably represent filenames because spaces, glob characters, and empty values are data. Arrays preserve argument boundaries; quote `${array[@]}` to pass each member separately. `IFS= read -r` avoids trimming whitespace and interpreting backslashes, and a final unterminated line may require an explicit fallback condition.

Print an array without losing boundaries
#!/usr/bin/env bash
set -Eeuo pipefail

files=("report one.txt" "report two.txt")
for file in "${files[@]}"; do
  printf '<%s>\n' "$file"
done
Output
<report one.txt>
<report two.txt>
Back to quick reference ↑
04

Use Bash-native tests and small functions

`[[ ... ]]` avoids word splitting and pathname expansion and supports Bash pattern matching. `(( ... ))` is the natural numeric context, but an arithmetic result of zero has false command status and can interact with errexit. Functions share shell state; use local for temporary variables and return status for success or failure rather than printing encoded status values.

Classify a path in a function
#!/usr/bin/env bash
set -Eeuo pipefail

describe() {
  local path=$1
  if [[ -f $path ]]; then
    printf 'file: %s\n' "$path"
  elif [[ -d $path ]]; then
    printf 'directory: %s\n' "$path"
  else
    printf 'missing: %s\n' "$path" >&2
    return 1
  fi
}

describe .
Back to quick reference ↑
05

Parse short options with getopts

getopts is a Bash builtin for short options. A leading colon in the option specification enables silent error reporting so the script can produce its own usage messages. OPTARG contains an option argument and OPTIND identifies the next operand; shift only after parsing is complete.

Parse output and verbosity options
#!/usr/bin/env bash
set -Eeuo pipefail

output=-
verbose=0
while getopts ':o:v' option; do
  case $option in
    o) output=$OPTARG ;;
    v) verbose=1 ;;
    :) printf 'option -%s needs a value\n' "$OPTARG" >&2; exit 2 ;;
    ?) printf 'unknown option: -%s\n' "$OPTARG" >&2; exit 2 ;;
  esac
done
shift "$((OPTIND - 1))"
printf 'output=%s verbose=%s operands=%s\n' "$output" "$verbose" "$#"
Back to quick reference ↑
06

Initialize cleanup state before installing traps

mktemp creates a collision-resistant temporary path; check that it succeeds before registering cleanup. A single-quoted trap action expands variables when the trap runs, so initialize those variables first and keep them readonly when practical. Quote the path and use `--`; never derive a recursive-removal target from unchecked user input.

Create and clean a private work directory
#!/usr/bin/env bash
set -Eeuo pipefail

workdir=$(mktemp -d)
readonly workdir
trap 'rm -rf -- "$workdir"' EXIT

printf 'temporary data\n' > "$workdir/result.txt"
wc -l < "$workdir/result.txt"
Back to quick reference ↑
07

Parse and lint before execution

`bash -n` catches syntax errors without running commands, but it cannot prove runtime behavior. ShellCheck identifies many expansion and portability hazards and explains each diagnostic. Add focused tests around argument parsing, failure cleanup, unusual filenames, empty input, and the external commands a script orchestrates.

Run two complementary static checks
bash -n script.sh
shellcheck --shell=bash script.sh

Note: ShellCheck is a separate tool and may need installation through the operating system's package manager.

Back to quick reference ↑

Sources and further reading

References

Authoritative documentation used to verify and expand this cheat sheet.

  1. Free Software FoundationBash Reference Manualgnu.org
  2. Free Software FoundationBash Conditional Expressionsgnu.org
  3. Free Software FoundationBash Builtinsgnu.org
  4. ShellCheck ProjectShellCheck Wikishellcheck.net
  5. GNU Projectmktemp invocationgnu.org

Help us improve

Found a typo or missing example?

Tell us what would make this cheat sheet clearer, more complete, or more useful.

Share feedback