Przejdลบ do treล›ci

๐Ÿž Debugging Scripts

Debugging shell scripts requires understanding how the shell executes commands, expands variables, handles errors, and manages processes. This module provides practical techniques for diagnosing issues in POSIXโ€‘compatible scripts.


๐ŸŽ“ Who This Is For

  • Engineers debugging nonโ€‘trivial shell scripts
  • DevOps/SRE teams maintaining CI/CD pipelines
  • Developers working with pipelines, subshells, or environment issues
  • Anyone needing reliable troubleshooting techniques

๐Ÿงฉ Role in the Ecosystem

Debugging tools in POSIX shells are minimal compared to full programming languages. Effective debugging relies on:

  • Tracing execution
  • Inspecting variables
  • Understanding subshell behavior
  • Checking exit codes
  • Logging intermediate state

These techniques are essential for writing predictable, productionโ€‘grade automation.


๐Ÿงฉ Key Concepts

1. Exit Codes

Every command returns a status:

1
echo $?    # last exit code

2. Tracing

Shells can print each executed command:

1
set -x

3. Subshell Isolation

Variables modified in subshells do not persist (see Subshells).

4. Expansion Debugging

Many bugs come from incorrect quoting or expansion (see Parameter Expansion).


๐Ÿ”ง Techniques

Enable Tracing

1
set -x

Disable:

1
set +x

Strict Mode (bash/ksh)

1
set -euo pipefail
1
2
3
debug() {
  printf '[DEBUG] %s\n' "$*" >&2
}

Inspect Variables

1
printf 'x="%s"\n' "$x"

Check Exit Codes Explicitly

1
2
3
command
status=$?
echo "exit code: $status"

Debug Pipelines

1
set -o pipefail

Debug Subshell Behavior

1
2
echo "parent $$"
( echo "subshell $$" )

โš ๏ธ Limitations & Pitfalls

  • set -e behaves inconsistently across shells
  • Pipelines hide failures without pipefail
  • Subshells discard variable changes
  • Quoting errors often go unnoticed
  • Debug output may break scripts expecting clean stdout

๐Ÿง  When to Use These Techniques

  • Debugging CI/CD failures
  • Investigating unexpected variable values
  • Understanding pipeline behavior
  • Diagnosing environment propagation issues
  • Rewriting or refactoring legacy scripts

โŒ When Not to Use Them

  • In production scripts without disabling tracing
  • When debugging output must not appear on stderr
  • When strict mode breaks legacy behavior

โœ… Best Practices

  • Use tracing only temporarily
  • Log to stderr, not stdout
  • Prefer explicit exit code checks
  • Use set -euo pipefail in new bash scripts
  • Test under multiple shells (bash, dash, ash, ksh)
  • Keep debug helpers small and reusable

๐Ÿงช Testing Debugging Behavior

1
2
3
4
set -x
x=1
y=$((x + 1))
echo "$y"

Test pipeline failures:

1
2
3
set -o pipefail
false | true
echo $?   # 1

๐Ÿง  Summary

Debugging shell scripts requires deliberate techniques: tracing, inspecting variables, checking exit codes, and understanding subshell behavior. Used correctly, these tools make shell scripts predictable, maintainable, and productionโ€‘ready