Hub for reusable patterns for writing reliable bash scripts for automation, validation, and workflow management.
Reliable bash automation requires fail-fast error handling, atomic operations, and clear feedback. These patterns prevent silent failures, data corruption, and debugging nightmares.
Core Principles:
- Fail-Fast: Exit immediately on errors
- Atomic: Operations complete fully or not at all
- Idempotent: Running twice has same effect as running once
- Clear Feedback: Always say what succeeded or failed
- Exit Codes: 0 = success, non-zero = specific failure
Essential patterns for catching errors early and providing actionable feedback.
Patterns:
- Fail-Fast Error Handling -
set -euo pipefailfor immediate error detection - Clear Error Reporting - Helper functions for error/warn/success messages
- Timeout Protection - Prevent scripts hanging on external services
- Polling External Services - Bounded waits with clear feedback
See ../guides/scripting/error-handling-patterns.md for detailed implementation.
Patterns for preventing data corruption and enabling safe rollback.
Patterns: 5. Atomic State Updates - Temp file + atomic move pattern 6. Safe File Operations - Backup before modify, test before apply 7. Event Hooks - Pre/post state transition hooks 8. Configuration Validation - Validate configs and environment 9. Tool Version Checks - Ensure dependencies meet requirements 10. Dry Run Mode - Test script logic without side effects
See ../guides/scripting/safe-operations-patterns.md for detailed implementation.
| Pattern | Purpose | Exit Code on Error |
|---|---|---|
| Fail-Fast | Stop on any error | Command's exit code |
| Error Reporting | Clear user feedback | Customizable (0-5) |
| Timeout Protection | Prevent hanging | 5 (timeout), 1 (failure) |
| Atomic Updates | Prevent corruption | N/A (transactional) |
| Backup Before Modify | Enable rollback | 1 (general error) |
| Config Validation | Catch setup issues early | 2 (missing), 3 (invalid) |
| Version Checks | Ensure compatibility | 2 (version too old) |
| Dry Run | Test safely | 0 (no errors) |
Every automation script should start with:
#!/bin/bash
set -euo pipefail
# Configuration
REPO_ROOT=$(git rev-parse --show-toplevel)
cd "$REPO_ROOT"
# Helper functions
function error() {
echo "ERROR: $1" >&2
exit "${2:-1}"
}
function success() {
echo "✓ $1"
}
# Script logic here- Always use
set -euo pipefailat start of every script - Use atomic updates (temp file + mv) for state files
- Backup before modify for important files
- Clear error messages with specific exit codes
- Timeout protection for external calls
- Validate inputs before using them
- Provide dry-run mode for destructive operations
- Poll, don't spin when waiting for external services
- Use functions for reusable logic
- Document exit codes in script comments
Standardize exit codes for consistent error handling:
| Exit Code | Meaning | Example |
|---|---|---|
| 0 | Success | All operations completed |
| 1 | General error | Command failed, unspecified |
| 2 | Missing file/dependency | package.json not found |
| 3 | Configuration error | Invalid YAML, missing field |
| 4 | External service failure | API unreachable |
| 5 | Timeout | Operation exceeded time limit |
command || true # Bad: Swallows all errorsecho "$value" > state.json # Bad: Inconsistent if interruptedwhile ! curl https://api.example.com; do
sleep 1 # Bad: Could wait forever
doneRelated Documentation:
- ../guides/scripting/error-handling-patterns.md - Fail-fast, error reporting, timeouts, polling
- ../guides/scripting/safe-operations-patterns.md - Atomic updates, backups, hooks, validation
- ../configs/quality-gates.md - Validation gate patterns
- one-liners.md - Command quick reference