Script Valley
Bash Scripting for Developers
DevOps Scripting PatternsLesson 6.1

Bash script testing and debugging techniques

set -x tracing, bash -n syntax check, shellcheck static analysis, set -v verbose, PS4 variable, bats testing framework, assert functions, testing functions in isolation, debugging subshells

Debugging Bash Scripts

Bash debugging tools

Bash provides built-in tracing. Enable it per-script or for specific sections.

#!/usr/bin/env bash
set -euo pipefail

# Trace: prints every command before executing
set -x

# Custom PS4 shows file and line number
export PS4='+ ${BASH_SOURCE[0]}:${LINENO}: '

# Disable tracing for a noisy section
set +x
password=$(get_secret)
set -x

# Syntax check without executing
bash -n myscript.sh

ShellCheck: Static Analysis

# Install
apt install shellcheck    # Linux
brew install shellcheck   # macOS

# Run
shellcheck myscript.sh
shellcheck --severity=warning myscript.sh

# Inline disable for false positives
# shellcheck disable=SC2086
word_split_intentional $var

BATS: Bash Unit Testing

# test/logging.bats
#!/usr/bin/env bats

setup() {
  source "${BATS_TEST_DIRNAME}/../lib/logging.sh"
}

@test "log_info outputs to stderr" {
  run bash -c 'source lib/logging.sh; log_info "test message"'
  [ "$status" -eq 0 ]
  [[ "$output" =~ "INFO" ]]
  [[ "$output" =~ "test message" ]]
}

@test "log_error exits with non-zero on script errors" {
  run bash -c 'set -e; source lib/logging.sh; false'
  [ "$status" -ne 0 ]
}

Run ShellCheck in CI on every push — it catches quoting errors, uninitialized variables, and bad patterns before they hit production.

Up next

Managing secrets and environment variables in Bash

Sign in to track progress