Production Bash Scripting

VerifiedSafe

Provides best practices for writing production-quality Bash scripts, enforcing safety flags (set -euo pipefail), modern syntax ([[ ]], $( ), (( ))), and mandatory ShellCheck compliance. Helps prevent silent failures and data corruption by ensuring scripts are robust and maintainable. Use this skill when creating or modifying any .sh file, shell script, or pre-commit hook.

Sby Skills Guide Bot
DevelopmentIntermediate
1306/2/2026
Claude Code
#bash#shell-scripting#shellcheck#automation

Recommended for

Our review

Guides writing production-quality Bash scripts using modern idioms and ShellCheck compliance.

Strengths

  • Enforces safety with set -euo pipefail
  • Encourages use of [[ ]] and quoting
  • Mandates ShellCheck
  • Provides clear patterns

Limitations

  • Only suitable for scripts under 200 lines
  • Not for complex logic or long-running services
  • Requires Bash 4+
When to use it

When writing or modifying shell scripts for automation, deployment, or system tasks.

When not to use it

For complex business logic, robust error recovery, or scripts exceeding 200 lines.

Security analysis

Safe
Quality score95/100

The skill provides safe Bash scripting guidelines, advocating for set -euo pipefail, variable quoting, and ShellCheck compliance. It contains no destructive commands or external payloads, and the cleanup template is standard practice. There is no instruction to execute harmful actions.

No concerns found

Examples

Write bash script with error handling
Write a bash script that takes a filename as argument and checks if it exists, with proper error handling using set -euo pipefail and ShellCheck compliance.
Create deploy script
Create a deploy script that builds the project and deploys to a remote server, following bash best practices.
Update pre-commit hook
Update the pre-commit hook file to run ShellCheck on all staged .sh files before commit.

name: bash description: >- Guide for writing production-quality bash scripts following modern idiomatic practices. Enforces set -euo pipefail, [[ ]] conditionals, ${var} syntax, ShellCheck compliance. Triggers on "bash script", "shell script", ".sh file", "write a script", "automation script", "bash function", "shellcheck", "bash template", "pre-commit hook", "deploy script", "build script", "install script", "setup script", "bash error handling", "bash arrays", "bash loop", "bash conditional", "parse arguments", "getopts", "bash logging", "#!/bin/bash", "source script", "dot script", "shell function", "edit script", "update script", "modify script", "change script", "edit .sh", "update .sh", "modify .sh", "statusline.sh", "hook script". PROACTIVE: MUST invoke BEFORE editing/writing ANY .sh file or pre-commit hook. allowed-tools: Read, Write, Edit, Bash, Glob, Grep

ABOUTME: Bash scripting skill for production-quality scripts with Bash 4.x+

ABOUTME: Emphasizes safety, readability, maintainability, and mandatory ShellCheck compliance

Bash Scripting Skill

Target: Bash 4.0+ with mandatory ShellCheck compliance.

Detailed patterns: See references/script-template.md and references/advanced-patterns.md


πŸ›‘ FILE OPERATION CHECKPOINT (BLOCKING)

Before EVERY Write or Edit tool call on a .sh file or shell script:

╔══════════════════════════════════════════════════════════════════╗
β•‘  πŸ›‘ STOP - BASH SKILL CHECK                                      β•‘
β•‘                                                                  β•‘
β•‘  You are about to modify a shell script.                         β•‘
β•‘                                                                  β•‘
β•‘  QUESTION: Is /bash skill currently active?                      β•‘
β•‘                                                                  β•‘
β•‘  If YES β†’ Proceed with the edit                                  β•‘
β•‘  If NO  β†’ STOP! Invoke /bash FIRST, then edit                    β•‘
β•‘                                                                  β•‘
β•‘  This check applies to:                                          β•‘
β•‘  βœ— Write tool with file_path ending in .sh                       β•‘
β•‘  βœ— Edit tool with file_path ending in .sh                        β•‘
β•‘  βœ— Files named "pre-commit", "post-commit", etc. (git hooks)     β•‘
β•‘  βœ— ANY shell script, regardless of conversation topic            β•‘
β•‘                                                                  β•‘
β•‘  Examples that REQUIRE this skill:                               β•‘
β•‘  - "update the statusline" (edits statusline.sh)                 β•‘
β•‘  - "add a feature to the hook" (edits pre-commit)                β•‘
β•‘  - "fix the deploy script" (edits deploy.sh)                     β•‘
β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•

Why this matters: Shell scripts without proper safety headers (set -euo pipefail) can fail silently or cause data corruption. The skill ensures ShellCheck compliance.


Quick Reference

| Pattern | Use | Avoid | |---------|-----|-------| | Conditionals | [[ "${var}" == "x" ]] | [ $var == "x" ] | | Variables | "${var}" (quoted) | $var (unquoted) | | Command sub | $(command) | `command` | | Arithmetic | (( count++ )) | let count++ | | Error handling | set -euo pipefail | No safety flags |


When to Use Bash

USE for (< 200 lines):

  • Quick automation tasks
  • Build/deployment scripts
  • System administration
  • Glue code between tools

DON'T USE for:

  • Complex business logic
  • Robust error handling with recovery
  • Long-running services
  • Code requiring unit testing

If script exceeds ~200 lines, consider Python or Go.


πŸ”„ RESUMED SESSION CHECKPOINT

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  SESSION RESUMED - BASH SKILL VERIFICATION                  β”‚
β”‚                                                             β”‚
β”‚  Before continuing:                                         β”‚
β”‚  1. Does script have set -euo pipefail?                     β”‚
β”‚  2. Are all variables quoted: "${var}"?                     β”‚
β”‚  3. Using [[ ]] conditionals (not [ ])?                     β”‚
β”‚  4. Run: shellcheck <script>.sh                             β”‚
β”‚  5. Re-invoke /bash if skill context was lost               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Mandatory Header

Every script MUST start with:

#!/bin/bash
set -euo pipefail

# -e: Exit on error
# -u: Error on unset variables
# -o pipefail: Pipeline fails on first error

Core Syntax Rules

Conditionals (Always [[ ]])

if [[ "${var}" =~ ^[0-9]+$ ]]; then
    echo "Numeric"
fi

if [[ -f "${file}" && -r "${file}" ]]; then
    echo "File exists and readable"
fi

Variable Expansion (Always quoted)

echo "Value: ${config_path}"
echo "Array: ${my_array[@]}"

Command Substitution

current_date=$(date +"%Y-%m-%d")
file_count=$(find . -type f | wc -l)

Arithmetic

(( count++ ))
(( total = value1 + value2 ))
if (( count > 10 )); then
    echo "Exceeded"
fi

Error Handling Patterns

Pattern 1: Need output AND status

output=$(complex_command 2>&1)
rc=$?
if [[ ${rc} -ne 0 ]]; then
    log_error "Failed: ${output}"
    return 1
fi

Pattern 2: Status check only

if ! simple_command --flag; then
    die "Command failed"
fi

# Or short form
simple_command || die "Failed"

Essential Functions

# Logging
log_info()  { echo "[INFO] $(date +%H:%M:%S) ${*}" >&2; }
log_error() { echo "[ERROR] $(date +%H:%M:%S) ${*}" >&2; }
die()       { log_error "${*}"; exit 1; }

# Validation
validate_file() {
    local -r f="${1}"
    [[ -f "${f}" ]] || die "Not found: ${f}"
    [[ -r "${f}" ]] || die "Not readable: ${f}"
}

# Cleanup
cleanup() {
    [[ -d "${TEMP_DIR:-}" ]] && rm -rf "${TEMP_DIR}"
}
trap cleanup EXIT

Argument Parsing

parse_arguments() {
    while [[ $# -gt 0 ]]; do
        case "${1}" in
            -h|--help)    help; exit 0 ;;
            -v|--verbose) VERBOSE=true; shift ;;
            -f|--file)
                [[ -z "${2:-}" ]] && die "-f requires argument"
                FILE="${2}"; shift 2
                ;;
            -*)           die "Unknown: ${1}" ;;
            *)            break ;;
        esac
    done
    ARGS=("${@}")
}

ShellCheck Compliance

All scripts MUST pass ShellCheck with zero warnings.

Common Fixes

| Warning | Fix | |---------|-----| | SC2086: Quote to prevent globbing | rm "${file}" not rm $file | | SC2155: Declare separately | local x; x=$(cmd) not local x=$(cmd) | | SC1090: Can't follow source | # shellcheck source=/dev/null | | SC2046: Quote command sub | Use while read instead of for x in $(cmd) |

Run ShellCheck

shellcheck script.sh
shellcheck -s bash script.sh
find . -name "*.sh" -exec shellcheck {} +

Arrays Quick Reference

Indexed Arrays

declare -a files=()
files+=("item")
for f in "${files[@]}"; do echo "${f}"; done
echo "Count: ${#files[@]}"

Associative Arrays (Bash 4+)

declare -A config=()
config["key"]="value"
for k in "${!config[@]}"; do echo "${k}=${config[${k}]}"; done

Security Rules

  1. Never use eval
  2. Sanitize all inputs
  3. Use absolute paths for system commands
  4. Use readonly for constants
  5. Don't store secrets in scripts

Checklist

Before script is complete:

  • [ ] set -euo pipefail at top
  • [ ] All variables use "${var}" syntax
  • [ ] Uses [[ ]] for conditionals
  • [ ] Uses $(command) for substitution
  • [ ] ShellCheck passes (zero warnings)
  • [ ] Has help() function
  • [ ] Has cleanup trap
  • [ ] Variables properly scoped (local/readonly)
  • [ ] If > 100 lines: Has bats tests

Full Template

See references/script-template.md for complete production script template.

Advanced Patterns

See references/advanced-patterns.md for:

  • Arrays and associative arrays
  • String manipulation
  • Parallel processing
  • Progress indicators
  • Input validation
  • bats-core testing
Related skills