Code Reference

Debugging

Bash · Reference cheat sheet

Debugging

Bash · Reference cheat sheet


📋 Overview

Debug bash with tracing (set -x), verbose mode, ShellCheck, and strategic logging. Reproduce with the same options and environment as production. Prefer small reproducible snippets over editing large scripts blindly.

🔧 Core concepts

ToolPurpose
set -x / set +xTrace expanded commands
set -vPrint input lines as read
PS4Prefix for set -x traces
bash -n scriptSyntax check only
bash -x scriptRun with trace
trapCatch ERR / DEBUG / EXIT
ShellCheckLint common bugs
printf '%q\n'Show shell-escaped values

ERR trap runs when a command fails (with set -e nuances). DEBUG trap runs before each command.

💡 Examples

Trace with context:

export PS4='+${BASH_SOURCE}:${LINENO}:${FUNCNAME[0]}: '
set -x
# … suspect code …
set +x

ERR trap:

trap 'echo "ERR at ${BASH_SOURCE}:${LINENO}: $BASH_COMMAND" >&2' ERR
set -euo pipefail

Inspect values:

declare -p var
printf 'args:'; printf ' <%q>' "$@"; echo
type -a cmd
command -v cmd

Dry syntax + lint:

bash -n ./deploy.sh
shellcheck -x ./deploy.sh

Conditional debug flag:

debug() { [[ "${DEBUG:-}" == 1 ]] && printf '%s\n' "$*" >&2; }
debug "port=$port"

⚠️ Pitfalls

  • set -x prints secrets—disable around credential handling or redact.
  • Tracing changes timing (Heisenbugs in races).
  • bash -n does not catch runtime logic errors.
  • Don’t leave set -x on in production cron output floods.
  • Pipeline failures need pipefail to surface in traces meaningfully.
  • Subshells complicate stack traces—note (…) boundaries.

On this page