[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CCYYN5WC1D04ZP3PGHGCHQ":3,"skill-same:01M6CCYYN5WC1D04ZP3PGHGCHQ":74},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":42,"linkOnly":43,"markdownContent":44,"markdownBody":45,"frontMatter":46,"refName":48,"commitSha":49,"skillDirectory":50,"forksCount":51,"repositoryHtmlUrl":52,"repositoryHomepageUrl":6,"ownerHtmlUrl":53,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":54,"install":55,"resources":67},"01M6CCYYN5WC1D04ZP3PGHGCHQ","bash-defensive-patterns",null,"Master defensive Bash programming techniques for production-grade scripts. Use when writing robust shell scripts, CI\u002FCD pipelines, or system utilities requiring fault tolerance and safety.","cercova-studios\u002F10x-swe","cercova-studios","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F217108198?v=4","01M6CCYGHXTH80N3BXRW6KESTE","Cercova Studios","01M6CCYGPADH5MJDR0VNNR775C",1,"MIT","https:\u002F\u002Fgithub.com\u002Fcercova-studios\u002F10x-swe\u002Fblob\u002Fmain\u002Fplugins\u002F10x-swe\u002Fskills\u002Fbash-defensive-patterns\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41],"bash defensive patterns","Bash","defensive","patterns","techniques","for","Utilities","CI\u002FCD","scripts","tolerance","when","fault tolerance","pipelines","Production","master","Safety","shell","shell scripts","programming","use","writing","ci","system","2026-11-10 10:12:30",false,"---\nname: bash-defensive-patterns\ndescription: Master defensive Bash programming techniques for production-grade scripts. Use when writing robust shell scripts, CI\u002FCD pipelines, or system utilities requiring fault tolerance and safety.\ndisable-model-invocation: true\n---\n\n# Bash Defensive Patterns\n\nComprehensive guidance for writing production-ready Bash scripts using defensive programming techniques, error handling, and safety best practices to prevent common pitfalls and ensure reliability.\n\n## When to Use This Skill\n\n- Writing production automation scripts\n- Building CI\u002FCD pipeline scripts\n- Creating system administration utilities\n- Developing error-resilient deployment automation\n- Writing scripts that must handle edge cases safely\n- Building maintainable shell script libraries\n- Implementing comprehensive logging and monitoring\n- Creating scripts that must work across different platforms\n\n## Core Defensive Principles\n\n### 1. Strict Mode\n\nEnable bash strict mode at the start of every script to catch errors early.\n\n```bash\n#!\u002Fbin\u002Fbash\nset -Eeuo pipefail  # Exit on error, unset variables, pipe failures\n```\n\n**Key flags:**\n\n- `set -E`: Inherit ERR trap in functions\n- `set -e`: Exit on any error (command returns non-zero)\n- `set -u`: Exit on undefined variable reference\n- `set -o pipefail`: Pipe fails if any command fails (not just last)\n\n### 2. Error Trapping and Cleanup\n\nImplement proper cleanup on script exit or error.\n\n```bash\n#!\u002Fbin\u002Fbash\nset -Eeuo pipefail\n\ntrap 'echo \"Error on line $LINENO\"' ERR\ntrap 'echo \"Cleaning up...\"; rm -rf \"$TMPDIR\"' EXIT\n\nTMPDIR=$(mktemp -d)\n# Script code here\n```\n\n### 3. Variable Safety\n\nAlways quote variables to prevent word splitting and globbing issues.\n\n```bash\n# Wrong - unsafe\ncp $source $dest\n\n# Correct - safe\ncp \"$source\" \"$dest\"\n\n# Required variables - fail with message if unset\n: \"${REQUIRED_VAR:?REQUIRED_VAR is not set}\"\n```\n\n### 4. Array Handling\n\nUse arrays safely for complex data handling.\n\n```bash\n# Safe array iteration\ndeclare -a items=(\"item 1\" \"item 2\" \"item 3\")\n\nfor item in \"${items[@]}\"; do\n    echo \"Processing: $item\"\ndone\n\n# Reading output into array safely\nmapfile -t lines \u003C \u003C(some_command)\nreadarray -t numbers \u003C \u003C(seq 1 10)\n```\n\n### 5. Conditional Safety\n\nUse `[[ ]]` for Bash-specific features, `[ ]` for POSIX.\n\n```bash\n# Bash - safer\nif [[ -f \"$file\" && -r \"$file\" ]]; then\n    content=$(\u003C\"$file\")\nfi\n\n# POSIX - portable\nif [ -f \"$file\" ] && [ -r \"$file\" ]; then\n    content=$(cat \"$file\")\nfi\n\n# Test for existence before operations\nif [[ -z \"${VAR:-}\" ]]; then\n    echo \"VAR is not set or is empty\"\nfi\n```\n\n## Fundamental Patterns\n\n### Pattern 1: Safe Script Directory Detection\n\n```bash\n#!\u002Fbin\u002Fbash\nset -Eeuo pipefail\n\n# Correctly determine script directory\nSCRIPT_DIR=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]}\")\" && pwd -P)\"\nSCRIPT_NAME=\"$(basename -- \"${BASH_SOURCE[0]}\")\"\n\necho \"Script location: $SCRIPT_DIR\u002F$SCRIPT_NAME\"\n```\n\n### Pattern 2: Comprehensive Function Templat\n\n```bash\n#!\u002Fbin\u002Fbash\nset -Eeuo pipefail\n\n# Prefix for functions: handle_*, process_*, check_*, validate_*\n# Include documentation and error handling\n\nvalidate_file() {\n    local -r file=\"$1\"\n    local -r message=\"${2:-File not found: $file}\"\n\n    if [[ ! -f \"$file\" ]]; then\n        echo \"ERROR: $message\" >&2\n        return 1\n    fi\n    return 0\n}\n\nprocess_files() {\n    local -r input_dir=\"$1\"\n    local -r output_dir=\"$2\"\n\n    # Validate inputs\n    [[ -d \"$input_dir\" ]] || { echo \"ERROR: input_dir not a directory\" >&2; return 1; }\n\n    # Create output directory if needed\n    mkdir -p \"$output_dir\" || { echo \"ERROR: Cannot create output_dir\" >&2; return 1; }\n\n    # Process files safely\n    while IFS= read -r -d '' file; do\n        echo \"Processing: $file\"\n        # Do work\n    done \u003C \u003C(find \"$input_dir\" -maxdepth 1 -type f -print0)\n\n    return 0\n}\n```\n\n### Pattern 3: Safe Temporary File Handling\n\n```bash\n#!\u002Fbin\u002Fbash\nset -Eeuo pipefail\n\ntrap 'rm -rf -- \"$TMPDIR\"' EXIT\n\n# Create temporary directory\nTMPDIR=$(mktemp -d) || { echo \"ERROR: Failed to create temp directory\" >&2; exit 1; }\n\n# Create temporary files in directory\nTMPFILE1=\"$TMPDIR\u002Ftemp1.txt\"\nTMPFILE2=\"$TMPDIR\u002Ftemp2.txt\"\n\n# Use temporary files\ntouch \"$TMPFILE1\" \"$TMPFILE2\"\n\necho \"Temp files created in: $TMPDIR\"\n```\n\n### Pattern 4: Robust Argument Parsing\n\n```bash\n#!\u002Fbin\u002Fbash\nset -Eeuo pipefail\n\n# Default values\nVERBOSE=false\nDRY_RUN=false\nOUTPUT_FILE=\"\"\nTHREADS=4\n\nusage() {\n    cat \u003C\u003CEOF\nUsage: $0 [OPTIONS]\n\nOptions:\n    -v, --verbose       Enable verbose output\n    -d, --dry-run       Run without making changes\n    -o, --output FILE   Output file path\n    -j, --jobs NUM      Number of parallel jobs\n    -h, --help          Show this help message\nEOF\n    exit \"${1:-0}\"\n}\n\n# Parse arguments\nwhile [[ $# -gt 0 ]]; do\n    case \"$1\" in\n        -v|--verbose)\n            VERBOSE=true\n            shift\n            ;;\n        -d|--dry-run)\n            DRY_RUN=true\n            shift\n            ;;\n        -o|--output)\n            OUTPUT_FILE=\"$2\"\n            shift 2\n            ;;\n        -j|--jobs)\n            THREADS=\"$2\"\n            shift 2\n            ;;\n        -h|--help)\n            usage 0\n            ;;\n        --)\n            shift\n            break\n            ;;\n        *)\n            echo \"ERROR: Unknown option: $1\" >&2\n            usage 1\n            ;;\n    esac\ndone\n\n# Validate required arguments\n[[ -n \"$OUTPUT_FILE\" ]] || { echo \"ERROR: -o\u002F--output is required\" >&2; usage 1; }\n```\n\n### Pattern 5: Structured Logging\n\n```bash\n#!\u002Fbin\u002Fbash\nset -Eeuo pipefail\n\n# Logging functions\nlog_info() {\n    echo \"[$(date +'%Y-%m-%d %H:%M:%S')] INFO: $*\" >&2\n}\n\nlog_warn() {\n    echo \"[$(date +'%Y-%m-%d %H:%M:%S')] WARN: $*\" >&2\n}\n\nlog_error() {\n    echo \"[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: $*\" >&2\n}\n\nlog_debug() {\n    if [[ \"${DEBUG:-0}\" == \"1\" ]]; then\n        echo \"[$(date +'%Y-%m-%d %H:%M:%S')] DEBUG: $*\" >&2\n    fi\n}\n\n# Usage\nlog_info \"Starting script\"\nlog_debug \"Debug information\"\nlog_warn \"Warning message\"\nlog_error \"Error occurred\"\n```\n\n### Pattern 6: Process Orchestration with Signals\n\n```bash\n#!\u002Fbin\u002Fbash\nset -Eeuo pipefail\n\n# Track background processes\nPIDS=()\n\ncleanup() {\n    log_info \"Shutting down...\"\n\n    # Terminate all background processes\n    for pid in \"${PIDS[@]}\"; do\n        if kill -0 \"$pid\" 2>\u002Fdev\u002Fnull; then\n            kill -TERM \"$pid\" 2>\u002Fdev\u002Fnull || true\n        fi\n    done\n\n    # Wait for graceful shutdown\n    for pid in \"${PIDS[@]}\"; do\n        wait \"$pid\" 2>\u002Fdev\u002Fnull || true\n    done\n}\n\ntrap cleanup SIGTERM SIGINT\n\n# Start background tasks\nbackground_task &\nPIDS+=($!)\n\nanother_task &\nPIDS+=($!)\n\n# Wait for all background processes\nwait\n```\n\n### Pattern 7: Safe File Operations\n\n```bash\n#!\u002Fbin\u002Fbash\nset -Eeuo pipefail\n\n# Use -i flag to move safely without overwriting\nsafe_move() {\n    local -r source=\"$1\"\n    local -r dest=\"$2\"\n\n    if [[ ! -e \"$source\" ]]; then\n        echo \"ERROR: Source does not exist: $source\" >&2\n        return 1\n    fi\n\n    if [[ -e \"$dest\" ]]; then\n        echo \"ERROR: Destination already exists: $dest\" >&2\n        return 1\n    fi\n\n    mv \"$source\" \"$dest\"\n}\n\n# Safe directory cleanup\nsafe_rmdir() {\n    local -r dir=\"$1\"\n\n    if [[ ! -d \"$dir\" ]]; then\n        echo \"ERROR: Not a directory: $dir\" >&2\n        return 1\n    fi\n\n    # Use -I flag to prompt before rm (BSD\u002FGNU compatible)\n    rm -rI -- \"$dir\"\n}\n\n# Atomic file writes\natomic_write() {\n    local -r target=\"$1\"\n    local -r tmpfile\n    tmpfile=$(mktemp) || return 1\n\n    # Write to temp file first\n    cat > \"$tmpfile\"\n\n    # Atomic rename\n    mv \"$tmpfile\" \"$target\"\n}\n```\n\n### Pattern 8: Idempotent Script Design\n\n```bash\n#!\u002Fbin\u002Fbash\nset -Eeuo pipefail\n\n# Check if resource already exists\nensure_directory() {\n    local -r dir=\"$1\"\n\n    if [[ -d \"$dir\" ]]; then\n        log_info \"Directory already exists: $dir\"\n        return 0\n    fi\n\n    mkdir -p \"$dir\" || {\n        log_error \"Failed to create directory: $dir\"\n        return 1\n    }\n\n    log_info \"Created directory: $dir\"\n}\n\n# Ensure configuration state\nensure_config() {\n    local -r config_file=\"$1\"\n    local -r default_value=\"$2\"\n\n    if [[ ! -f \"$config_file\" ]]; then\n        echo \"$default_value\" > \"$config_file\"\n        log_info \"Created config: $config_file\"\n    fi\n}\n\n# Rerunning script multiple times should be safe\nensure_directory \"\u002Fvar\u002Fcache\u002Fmyapp\"\nensure_config \"\u002Fetc\u002Fmyapp\u002Fconfig\" \"DEBUG=false\"\n```\n\n### Pattern 9: Safe Command Substitution\n\n```bash\n#!\u002Fbin\u002Fbash\nset -Eeuo pipefail\n\n# Use $() instead of backticks\nname=$(\u003C\"$file\")  # Modern, safe variable assignment from file\noutput=$(command -v python3)  # Get command location safely\n\n# Handle command substitution with error checking\nresult=$(command -v node) || {\n    log_error \"node command not found\"\n    return 1\n}\n\n# For multiple lines\nmapfile -t lines \u003C \u003C(grep \"pattern\" \"$file\")\n\n# NUL-safe iteration\nwhile IFS= read -r -d '' file; do\n    echo \"Processing: $file\"\ndone \u003C \u003C(find \u002Fpath -type f -print0)\n```\n\n### Pattern 10: Dry-Run Support\n\n```bash\n#!\u002Fbin\u002Fbash\nset -Eeuo pipefail\n\nDRY_RUN=\"${DRY_RUN:-false}\"\n\nrun_cmd() {\n    if [[ \"$DRY_RUN\" == \"true\" ]]; then\n        echo \"[DRY RUN] Would execute: $*\"\n        return 0\n    fi\n\n    \"$@\"\n}\n\n# Usage\nrun_cmd cp \"$source\" \"$dest\"\nrun_cmd rm \"$file\"\nrun_cmd chown \"$owner\" \"$target\"\n```\n\n## Advanced Defensive Techniques\n\n### Named Parameters Pattern\n\n```bash\n#!\u002Fbin\u002Fbash\nset -Eeuo pipefail\n\nprocess_data() {\n    local input_file=\"\"\n    local output_dir=\"\"\n    local format=\"json\"\n\n    # Parse named parameters\n    while [[ $# -gt 0 ]]; do\n        case \"$1\" in\n            --input=*)\n                input_file=\"${1#*=}\"\n                ;;\n            --output=*)\n                output_dir=\"${1#*=}\"\n                ;;\n            --format=*)\n                format=\"${1#*=}\"\n                ;;\n            *)\n                echo \"ERROR: Unknown parameter: $1\" >&2\n                return 1\n                ;;\n        esac\n        shift\n    done\n\n    # Validate required parameters\n    [[ -n \"$input_file\" ]] || { echo \"ERROR: --input is required\" >&2; return 1; }\n    [[ -n \"$output_dir\" ]] || { echo \"ERROR: --output is required\" >&2; return 1; }\n}\n```\n\n### Dependency Checking\n\n```bash\n#!\u002Fbin\u002Fbash\nset -Eeuo pipefail\n\ncheck_dependencies() {\n    local -a missing_deps=()\n    local -a required=(\"jq\" \"curl\" \"git\")\n\n    for cmd in \"${required[@]}\"; do\n        if ! command -v \"$cmd\" &>\u002Fdev\u002Fnull; then\n            missing_deps+=(\"$cmd\")\n        fi\n    done\n\n    if [[ ${#missing_deps[@]} -gt 0 ]]; then\n        echo \"ERROR: Missing required commands: ${missing_deps[*]}\" >&2\n        return 1\n    fi\n}\n\ncheck_dependencies\n```\n\n## Best Practices Summary\n\n1. **Always use strict mode** - `set -Eeuo pipefail`\n2. **Quote all variables** - `\"$variable\"` prevents word splitting\n3. **Use [[]] conditionals** - More robust than [ ]\n4. **Implement error trapping** - Catch and handle errors gracefully\n5. **Validate all inputs** - Check file existence, permissions, formats\n6. **Use functions for reusability** - Prefix with meaningful names\n7. **Implement structured logging** - Include timestamps and levels\n8. **Support dry-run mode** - Allow users to preview changes\n9. **Handle temporary files safely** - Use mktemp, cleanup with trap\n10. **Design for idempotency** - Scripts should be safe to rerun\n11. **Document requirements** - List dependencies and minimum versions\n12. **Test error paths** - Ensure error handling works correctly\n13. **Use `command -v`** - Safer than `which` for checking executables\n14. **Prefer printf over echo** - More predictable across systems\n\n## Resources\n\n- **Bash Strict Mode**: http:\u002F\u002Fredsymbol.net\u002Farticles\u002Funofficial-bash-strict-mode\u002F\n- **Google Shell Style Guide**: https:\u002F\u002Fgoogle.github.io\u002Fstyleguide\u002Fshellguide.html\n- **Defensive BASH Programming**: https:\u002F\u002Fwww.lifepipe.net\u002F\n","# Bash Defensive Patterns\n\nComprehensive guidance for writing production-ready Bash scripts using defensive programming techniques, error handling, and safety best practices to prevent common pitfalls and ensure reliability.\n\n## When to Use This Skill\n\n- Writing production automation scripts\n- Building CI\u002FCD pipeline scripts\n- Creating system administration utilities\n- Developing error-resilient deployment automation\n- Writing scripts that must handle edge cases safely\n- Building maintainable shell script libraries\n- Implementing comprehensive logging and monitoring\n- Creating scripts that must work across different platforms\n\n## Core Defensive Principles\n\n### 1. Strict Mode\n\nEnable bash strict mode at the start of every script to catch errors early.\n\n```bash\n#!\u002Fbin\u002Fbash\nset -Eeuo pipefail  # Exit on error, unset variables, pipe failures\n```\n\n**Key flags:**\n\n- `set -E`: Inherit ERR trap in functions\n- `set -e`: Exit on any error (command returns non-zero)\n- `set -u`: Exit on undefined variable reference\n- `set -o pipefail`: Pipe fails if any command fails (not just last)\n\n### 2. Error Trapping and Cleanup\n\nImplement proper cleanup on script exit or error.\n\n```bash\n#!\u002Fbin\u002Fbash\nset -Eeuo pipefail\n\ntrap 'echo \"Error on line $LINENO\"' ERR\ntrap 'echo \"Cleaning up...\"; rm -rf \"$TMPDIR\"' EXIT\n\nTMPDIR=$(mktemp -d)\n# Script code here\n```\n\n### 3. Variable Safety\n\nAlways quote variables to prevent word splitting and globbing issues.\n\n```bash\n# Wrong - unsafe\ncp $source $dest\n\n# Correct - safe\ncp \"$source\" \"$dest\"\n\n# Required variables - fail with message if unset\n: \"${REQUIRED_VAR:?REQUIRED_VAR is not set}\"\n```\n\n### 4. Array Handling\n\nUse arrays safely for complex data handling.\n\n```bash\n# Safe array iteration\ndeclare -a items=(\"item 1\" \"item 2\" \"item 3\")\n\nfor item in \"${items[@]}\"; do\n    echo \"Processing: $item\"\ndone\n\n# Reading output into array safely\nmapfile -t lines \u003C \u003C(some_command)\nreadarray -t numbers \u003C \u003C(seq 1 10)\n```\n\n### 5. Conditional Safety\n\nUse `[[ ]]` for Bash-specific features, `[ ]` for POSIX.\n\n```bash\n# Bash - safer\nif [[ -f \"$file\" && -r \"$file\" ]]; then\n    content=$(\u003C\"$file\")\nfi\n\n# POSIX - portable\nif [ -f \"$file\" ] && [ -r \"$file\" ]; then\n    content=$(cat \"$file\")\nfi\n\n# Test for existence before operations\nif [[ -z \"${VAR:-}\" ]]; then\n    echo \"VAR is not set or is empty\"\nfi\n```\n\n## Fundamental Patterns\n\n### Pattern 1: Safe Script Directory Detection\n\n```bash\n#!\u002Fbin\u002Fbash\nset -Eeuo pipefail\n\n# Correctly determine script directory\nSCRIPT_DIR=\"$(cd -- \"$(dirname -- \"${BASH_SOURCE[0]}\")\" && pwd -P)\"\nSCRIPT_NAME=\"$(basename -- \"${BASH_SOURCE[0]}\")\"\n\necho \"Script location: $SCRIPT_DIR\u002F$SCRIPT_NAME\"\n```\n\n### Pattern 2: Comprehensive Function Templat\n\n```bash\n#!\u002Fbin\u002Fbash\nset -Eeuo pipefail\n\n# Prefix for functions: handle_*, process_*, check_*, validate_*\n# Include documentation and error handling\n\nvalidate_file() {\n    local -r file=\"$1\"\n    local -r message=\"${2:-File not found: $file}\"\n\n    if [[ ! -f \"$file\" ]]; then\n        echo \"ERROR: $message\" >&2\n        return 1\n    fi\n    return 0\n}\n\nprocess_files() {\n    local -r input_dir=\"$1\"\n    local -r output_dir=\"$2\"\n\n    # Validate inputs\n    [[ -d \"$input_dir\" ]] || { echo \"ERROR: input_dir not a directory\" >&2; return 1; }\n\n    # Create output directory if needed\n    mkdir -p \"$output_dir\" || { echo \"ERROR: Cannot create output_dir\" >&2; return 1; }\n\n    # Process files safely\n    while IFS= read -r -d '' file; do\n        echo \"Processing: $file\"\n        # Do work\n    done \u003C \u003C(find \"$input_dir\" -maxdepth 1 -type f -print0)\n\n    return 0\n}\n```\n\n### Pattern 3: Safe Temporary File Handling\n\n```bash\n#!\u002Fbin\u002Fbash\nset -Eeuo pipefail\n\ntrap 'rm -rf -- \"$TMPDIR\"' EXIT\n\n# Create temporary directory\nTMPDIR=$(mktemp -d) || { echo \"ERROR: Failed to create temp directory\" >&2; exit 1; }\n\n# Create temporary files in directory\nTMPFILE1=\"$TMPDIR\u002Ftemp1.txt\"\nTMPFILE2=\"$TMPDIR\u002Ftemp2.txt\"\n\n# Use temporary files\ntouch \"$TMPFILE1\" \"$TMPFILE2\"\n\necho \"Temp files created in: $TMPDIR\"\n```\n\n### Pattern 4: Robust Argument Parsing\n\n```bash\n#!\u002Fbin\u002Fbash\nset -Eeuo pipefail\n\n# Default values\nVERBOSE=false\nDRY_RUN=false\nOUTPUT_FILE=\"\"\nTHREADS=4\n\nusage() {\n    cat \u003C\u003CEOF\nUsage: $0 [OPTIONS]\n\nOptions:\n    -v, --verbose       Enable verbose output\n    -d, --dry-run       Run without making changes\n    -o, --output FILE   Output file path\n    -j, --jobs NUM      Number of parallel jobs\n    -h, --help          Show this help message\nEOF\n    exit \"${1:-0}\"\n}\n\n# Parse arguments\nwhile [[ $# -gt 0 ]]; do\n    case \"$1\" in\n        -v|--verbose)\n            VERBOSE=true\n            shift\n            ;;\n        -d|--dry-run)\n            DRY_RUN=true\n            shift\n            ;;\n        -o|--output)\n            OUTPUT_FILE=\"$2\"\n            shift 2\n            ;;\n        -j|--jobs)\n            THREADS=\"$2\"\n            shift 2\n            ;;\n        -h|--help)\n            usage 0\n            ;;\n        --)\n            shift\n            break\n            ;;\n        *)\n            echo \"ERROR: Unknown option: $1\" >&2\n            usage 1\n            ;;\n    esac\ndone\n\n# Validate required arguments\n[[ -n \"$OUTPUT_FILE\" ]] || { echo \"ERROR: -o\u002F--output is required\" >&2; usage 1; }\n```\n\n### Pattern 5: Structured Logging\n\n```bash\n#!\u002Fbin\u002Fbash\nset -Eeuo pipefail\n\n# Logging functions\nlog_info() {\n    echo \"[$(date +'%Y-%m-%d %H:%M:%S')] INFO: $*\" >&2\n}\n\nlog_warn() {\n    echo \"[$(date +'%Y-%m-%d %H:%M:%S')] WARN: $*\" >&2\n}\n\nlog_error() {\n    echo \"[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: $*\" >&2\n}\n\nlog_debug() {\n    if [[ \"${DEBUG:-0}\" == \"1\" ]]; then\n        echo \"[$(date +'%Y-%m-%d %H:%M:%S')] DEBUG: $*\" >&2\n    fi\n}\n\n# Usage\nlog_info \"Starting script\"\nlog_debug \"Debug information\"\nlog_warn \"Warning message\"\nlog_error \"Error occurred\"\n```\n\n### Pattern 6: Process Orchestration with Signals\n\n```bash\n#!\u002Fbin\u002Fbash\nset -Eeuo pipefail\n\n# Track background processes\nPIDS=()\n\ncleanup() {\n    log_info \"Shutting down...\"\n\n    # Terminate all background processes\n    for pid in \"${PIDS[@]}\"; do\n        if kill -0 \"$pid\" 2>\u002Fdev\u002Fnull; then\n            kill -TERM \"$pid\" 2>\u002Fdev\u002Fnull || true\n        fi\n    done\n\n    # Wait for graceful shutdown\n    for pid in \"${PIDS[@]}\"; do\n        wait \"$pid\" 2>\u002Fdev\u002Fnull || true\n    done\n}\n\ntrap cleanup SIGTERM SIGINT\n\n# Start background tasks\nbackground_task &\nPIDS+=($!)\n\nanother_task &\nPIDS+=($!)\n\n# Wait for all background processes\nwait\n```\n\n### Pattern 7: Safe File Operations\n\n```bash\n#!\u002Fbin\u002Fbash\nset -Eeuo pipefail\n\n# Use -i flag to move safely without overwriting\nsafe_move() {\n    local -r source=\"$1\"\n    local -r dest=\"$2\"\n\n    if [[ ! -e \"$source\" ]]; then\n        echo \"ERROR: Source does not exist: $source\" >&2\n        return 1\n    fi\n\n    if [[ -e \"$dest\" ]]; then\n        echo \"ERROR: Destination already exists: $dest\" >&2\n        return 1\n    fi\n\n    mv \"$source\" \"$dest\"\n}\n\n# Safe directory cleanup\nsafe_rmdir() {\n    local -r dir=\"$1\"\n\n    if [[ ! -d \"$dir\" ]]; then\n        echo \"ERROR: Not a directory: $dir\" >&2\n        return 1\n    fi\n\n    # Use -I flag to prompt before rm (BSD\u002FGNU compatible)\n    rm -rI -- \"$dir\"\n}\n\n# Atomic file writes\natomic_write() {\n    local -r target=\"$1\"\n    local -r tmpfile\n    tmpfile=$(mktemp) || return 1\n\n    # Write to temp file first\n    cat > \"$tmpfile\"\n\n    # Atomic rename\n    mv \"$tmpfile\" \"$target\"\n}\n```\n\n### Pattern 8: Idempotent Script Design\n\n```bash\n#!\u002Fbin\u002Fbash\nset -Eeuo pipefail\n\n# Check if resource already exists\nensure_directory() {\n    local -r dir=\"$1\"\n\n    if [[ -d \"$dir\" ]]; then\n        log_info \"Directory already exists: $dir\"\n        return 0\n    fi\n\n    mkdir -p \"$dir\" || {\n        log_error \"Failed to create directory: $dir\"\n        return 1\n    }\n\n    log_info \"Created directory: $dir\"\n}\n\n# Ensure configuration state\nensure_config() {\n    local -r config_file=\"$1\"\n    local -r default_value=\"$2\"\n\n    if [[ ! -f \"$config_file\" ]]; then\n        echo \"$default_value\" > \"$config_file\"\n        log_info \"Created config: $config_file\"\n    fi\n}\n\n# Rerunning script multiple times should be safe\nensure_directory \"\u002Fvar\u002Fcache\u002Fmyapp\"\nensure_config \"\u002Fetc\u002Fmyapp\u002Fconfig\" \"DEBUG=false\"\n```\n\n### Pattern 9: Safe Command Substitution\n\n```bash\n#!\u002Fbin\u002Fbash\nset -Eeuo pipefail\n\n# Use $() instead of backticks\nname=$(\u003C\"$file\")  # Modern, safe variable assignment from file\noutput=$(command -v python3)  # Get command location safely\n\n# Handle command substitution with error checking\nresult=$(command -v node) || {\n    log_error \"node command not found\"\n    return 1\n}\n\n# For multiple lines\nmapfile -t lines \u003C \u003C(grep \"pattern\" \"$file\")\n\n# NUL-safe iteration\nwhile IFS= read -r -d '' file; do\n    echo \"Processing: $file\"\ndone \u003C \u003C(find \u002Fpath -type f -print0)\n```\n\n### Pattern 10: Dry-Run Support\n\n```bash\n#!\u002Fbin\u002Fbash\nset -Eeuo pipefail\n\nDRY_RUN=\"${DRY_RUN:-false}\"\n\nrun_cmd() {\n    if [[ \"$DRY_RUN\" == \"true\" ]]; then\n        echo \"[DRY RUN] Would execute: $*\"\n        return 0\n    fi\n\n    \"$@\"\n}\n\n# Usage\nrun_cmd cp \"$source\" \"$dest\"\nrun_cmd rm \"$file\"\nrun_cmd chown \"$owner\" \"$target\"\n```\n\n## Advanced Defensive Techniques\n\n### Named Parameters Pattern\n\n```bash\n#!\u002Fbin\u002Fbash\nset -Eeuo pipefail\n\nprocess_data() {\n    local input_file=\"\"\n    local output_dir=\"\"\n    local format=\"json\"\n\n    # Parse named parameters\n    while [[ $# -gt 0 ]]; do\n        case \"$1\" in\n            --input=*)\n                input_file=\"${1#*=}\"\n                ;;\n            --output=*)\n                output_dir=\"${1#*=}\"\n                ;;\n            --format=*)\n                format=\"${1#*=}\"\n                ;;\n            *)\n                echo \"ERROR: Unknown parameter: $1\" >&2\n                return 1\n                ;;\n        esac\n        shift\n    done\n\n    # Validate required parameters\n    [[ -n \"$input_file\" ]] || { echo \"ERROR: --input is required\" >&2; return 1; }\n    [[ -n \"$output_dir\" ]] || { echo \"ERROR: --output is required\" >&2; return 1; }\n}\n```\n\n### Dependency Checking\n\n```bash\n#!\u002Fbin\u002Fbash\nset -Eeuo pipefail\n\ncheck_dependencies() {\n    local -a missing_deps=()\n    local -a required=(\"jq\" \"curl\" \"git\")\n\n    for cmd in \"${required[@]}\"; do\n        if ! command -v \"$cmd\" &>\u002Fdev\u002Fnull; then\n            missing_deps+=(\"$cmd\")\n        fi\n    done\n\n    if [[ ${#missing_deps[@]} -gt 0 ]]; then\n        echo \"ERROR: Missing required commands: ${missing_deps[*]}\" >&2\n        return 1\n    fi\n}\n\ncheck_dependencies\n```\n\n## Best Practices Summary\n\n1. **Always use strict mode** - `set -Eeuo pipefail`\n2. **Quote all variables** - `\"$variable\"` prevents word splitting\n3. **Use [[]] conditionals** - More robust than [ ]\n4. **Implement error trapping** - Catch and handle errors gracefully\n5. **Validate all inputs** - Check file existence, permissions, formats\n6. **Use functions for reusability** - Prefix with meaningful names\n7. **Implement structured logging** - Include timestamps and levels\n8. **Support dry-run mode** - Allow users to preview changes\n9. **Handle temporary files safely** - Use mktemp, cleanup with trap\n10. **Design for idempotency** - Scripts should be safe to rerun\n11. **Document requirements** - List dependencies and minimum versions\n12. **Test error paths** - Ensure error handling works correctly\n13. **Use `command -v`** - Safer than `which` for checking executables\n14. **Prefer printf over echo** - More predictable across systems\n\n## Resources\n\n- **Bash Strict Mode**: http:\u002F\u002Fredsymbol.net\u002Farticles\u002Funofficial-bash-strict-mode\u002F\n- **Google Shell Style Guide**: https:\u002F\u002Fgoogle.github.io\u002Fstyleguide\u002Fshellguide.html\n- **Defensive BASH Programming**: https:\u002F\u002Fwww.lifepipe.net\u002F\n",{"name":5,"description":7,"disable-model-invocation":47},true,"main","224d7699a283a75bd3f75d4d8b03b15aca0ae309","plugins\u002F10x-swe\u002Fskills\u002Fbash-defensive-patterns",0,"https:\u002F\u002Fgithub.com\u002Fcercova-studios\u002F10x-swe","https:\u002F\u002Fgithub.com\u002Fcercova-studios","2026-11-12 07:39:44",{"source":8,"skillName":5,"commands":56,"prompt":66,"zipAvailable":47},[57,60,63],{"tool":58,"command":59},"npx","npx skills add cercova-studios\u002F10x-swe --skill bash-defensive-patterns",{"tool":61,"command":62},"bunx","bunx skills add cercova-studios\u002F10x-swe --skill bash-defensive-patterns",{"tool":64,"command":65},"pnpm","pnpm dlx skills add cercova-studios\u002F10x-swe --skill bash-defensive-patterns","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fcercova-studios\u002F10x-swe\u002Fblob\u002Fmain\u002Fplugins\u002F10x-swe\u002Fskills\u002Fbash-defensive-patterns\u002FSKILL.md",[68],{"path":69,"resourceType":70,"resourceTypeDesc":71,"sizeBytes":72,"sourceHtmlUrl":73},"agents\u002Fopenai.yaml","REFERENCE","参考文档",43,"https:\u002F\u002Fgithub.com\u002Fcercova-studios\u002F10x-swe\u002Fblob\u002Fmain\u002Fplugins\u002F10x-swe\u002Fskills\u002Fbash-defensive-patterns\u002Fagents\u002Fopenai.yaml",[75,115,151,171,190,202],{"skillNo":76,"name":77,"nameZh":6,"description":78,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":79,"licenseFileUrl":80,"sourceHtmlUrl":81,"categories":82,"keywords":88,"publishedAt":42},"01M6CD3T6EQ9N5KPNXCM6ABHVA","turnstile-spin","Set up Cloudflare Turnstile end-to-end in a project. Scan the codebase, create the widget via the Cloudflare API, embed it where user requests need bot verification (form submissions, SPA actions, API endpoints, download links, comment or vote submissions, etc.), wire canonical server-side siteverify in the customer's existing backend, validate, and persist the skill. Load this when a user asks to add Turnstile, set up CAPTCHA, protect a form or endpoint from bots, or fix a Turnstile integration. Uses Cloudflare's documented Turnstile contract.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fcercova-studios\u002F10x-swe\u002Fblob\u002Fmain\u002Fplugins\u002F10x-swe\u002Fskills\u002Fturnstile-spin\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fcercova-studios\u002F10x-swe\u002Fblob\u002Fmain\u002Fplugins\u002F10x-swe\u002Fskills\u002Fturnstile-spin\u002FSKILL.md",[83],{"categoryNo":84,"categoryName":85,"taxonomyType":86,"taxonomyTypeDesc":87},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",[89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,29],"turnstile spin","SET","nextjs","actions","up","fix","cloudflare","bot","api","permissions","create","astro","server","verification","plugin","endpoints","customer","backend","sveltekit","integration","app","bots","spa","project","end","SWE",{"skillNo":116,"name":117,"nameZh":6,"description":118,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":79,"licenseFileUrl":119,"sourceHtmlUrl":120,"categories":121,"keywords":133,"publishedAt":42},"01M6CD0BJYRNV610HYYPX933RE","frontend-design","Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.","https:\u002F\u002Fgithub.com\u002Fcercova-studios\u002F10x-swe\u002Fblob\u002Fmain\u002Fplugins\u002F10x-swe\u002Fskills\u002Ffrontend-design\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fcercova-studios\u002F10x-swe\u002Fblob\u002Fmain\u002Fplugins\u002F10x-swe\u002Fskills\u002Ffrontend-design\u002FSKILL.md",[122,125,128],{"categoryNo":123,"categoryName":124,"taxonomyType":86,"taxonomyTypeDesc":87},"01JBSEEDCAT000000000000009","前端开发",{"categoryNo":126,"categoryName":127,"taxonomyType":86,"taxonomyTypeDesc":87},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":129,"categoryName":130,"taxonomyType":131,"taxonomyTypeDesc":132},"01JBSEEDCAT000000000000032","设计师","PROFESSION","适用职业",[134,135,136,99,137,138,139,140,141,32,38,142,143,144,145,146,147,29,148,149,150],"frontend design","frontend","design","web","quality","applications","creative","web components","code","components","user","generic","aesthetics","pages","with","high","build",{"skillNo":152,"name":153,"nameZh":6,"description":154,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":155,"categories":156,"keywords":157,"publishedAt":42},"01M6CD4QX8C4DST98AY21HEYCM","source-insights","Prepare inspected source evidence, preserve exact citations, and publish reviewed insights into an explicit local library.","https:\u002F\u002Fgithub.com\u002Fcercova-studios\u002F10x-swe\u002Fblob\u002Fmain\u002Fplugins\u002Fknowledge\u002Fskills\u002Fsource-insights\u002FSKILL.md",[],[158,159,160,161,162,163,164,165,166,167,168,169,170],"source insights","insights","source","publish","Citations","evidence","library","workflows","prepare","session","global","local","preserve",{"skillNo":172,"name":173,"nameZh":6,"description":174,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":175,"categories":176,"keywords":180,"publishedAt":42},"01M6CD4N1HVNC1EXPEBZT7YS31","skill-graph","Discover skills and workflows through independent lexical search, relationship paths and a terminal graph.","https:\u002F\u002Fgithub.com\u002Fcercova-studios\u002F10x-swe\u002Fblob\u002Fmain\u002Fplugins\u002Fknowledge\u002Fskills\u002Fskill-graph\u002FSKILL.md",[177],{"categoryNo":178,"categoryName":179,"taxonomyType":86,"taxonomyTypeDesc":87},"01JBSEEDCAT000000000000023","Skill与智能体开发",[181,182,103,165,183,184,185,168,186,187,188,114,189],"graph","skill graph","terminal","10x","search","discover skills","discover","paths","relationship",{"skillNo":191,"name":192,"nameZh":6,"description":193,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":194,"categories":195,"keywords":196,"publishedAt":42},"01M6CD4HQKXNZ57YEGD8QVK6Z6","session-search","Recall public session turns with exact provenance, bounded excerpts and independent piped exports.","https:\u002F\u002Fgithub.com\u002Fcercova-studios\u002F10x-swe\u002Fblob\u002Fmain\u002Fplugins\u002Fknowledge\u002Fskills\u002Fsession-search\u002FSKILL.md",[],[185,167,197,198,165,199,200,168,148,159,160,201],"session search","public","provenance","recall","bounded",{"skillNo":203,"name":204,"nameZh":6,"description":205,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":206,"categories":207,"keywords":214,"publishedAt":42},"01M6CD4ET7DVNBYPDAMAYMSK2T","newsletter","Produce a private local AI newsletter from bounded public research, with cited deep dives, HTML\u002FMarkdown output, Dagu scheduling and seven-day retention.","https:\u002F\u002Fgithub.com\u002Fcercova-studios\u002F10x-swe\u002Fblob\u002Fmain\u002Fplugins\u002Fknowledge\u002Fskills\u002Fnewsletter\u002FSKILL.md",[208,211],{"categoryNo":209,"categoryName":210,"taxonomyType":86,"taxonomyTypeDesc":87},"01JBSEEDCAT000000000000005","邮件与沟通",{"categoryNo":212,"categoryName":213,"taxonomyType":86,"taxonomyTypeDesc":87},"01JBSEEDCAT000000000000021","资料检索与研究",[204,215,216,217,218,198,165,219,220,221,222,168,148,223,224,169,201,225],"local ai","dagu","produce","research","markdown","scheduling","html","daily","deep","retention","output"]