Use this skill when
- •Writing or reviewing Bash scripts for automation, CI/CD, or ops
- •Hardening shell scripts for safety and portability
Do not use this skill when
- •You need POSIX-only shell without Bash features
- •The task requires a higher-level language for complex logic
- •You need Windows-native scripting (PowerShell)
Instructions
- •Define script inputs, outputs, and failure modes.
- •Apply strict mode and safe argument parsing.
- •Implement core logic with defensive patterns.
- •Add tests and linting with Bats and ShellCheck.
Safety
- •Treat input as untrusted; avoid eval and unsafe globbing.
- •Prefer dry-run modes before destructive actions.
Focus Areas
- •Defensive programming with strict error handling
- •POSIX compliance and cross-platform portability
- •Safe argument parsing and input validation
- •Robust file operations and temporary resource management
- •Process orchestration and pipeline safety
- •Production-grade logging and error reporting
- •Comprehensive testing with Bats framework
- •Static analysis with ShellCheck and formatting with shfmt
- •Modern Bash 5.x features and best practices
- •CI/CD integration and automation workflows
Approach
- •Always use strict mode with
set -Eeuo pipefailand proper error trapping - •Quote all variable expansions to prevent word splitting and globbing issues
- •Prefer arrays and proper iteration over unsafe patterns like
for f in $(ls) - •Use
[[ ]]for Bash conditionals, fall back to[ ]for POSIX compliance - •Implement comprehensive argument parsing with
getoptsand usage functions - •Create temporary files and directories safely with
mktempand cleanup traps - •Prefer
printfoverechofor predictable output formatting - •Use command substitution
$()instead of backticks for readability - •Implement structured logging with timestamps and configurable verbosity
- •Design scripts to be idempotent and support dry-run modes
- •Use
shopt -s inherit_errexitfor better error propagation in Bash 4.4+ - •Employ
IFS=$'\n\t'to prevent unwanted word splitting on spaces - •Validate inputs with
: "${VAR:?message}"for required environment variables - •End option parsing with
--and userm -rf -- "$dir"for safe operations - •Support
--tracemode withset -xopt-in for detailed debugging - •Use
xargs -0with NUL boundaries for safe subprocess orchestration - •Employ
readarray/mapfilefor safe array population from command output - •Implement robust script directory detection:
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)" - •Use NUL-safe patterns:
find -print0 | while IFS= read -r -d '' file; do ...; done
Compatibility & Portability
- •Use
#!/usr/bin/env bashshebang for portability across systems - •Check Bash version at script start:
(( BASH_VERSINFO[0] >= 4 && BASH_VERSINFO[1] >= 4 ))for Bash 4.4+ features - •Validate required external commands exist:
command -v jq &>/dev/null || exit 1 - •Detect platform differences:
case "$(uname -s)" in Linux*) ... ;; Darwin*) ... ;; esac - •Handle GNU vs BSD tool differences (e.g.,
sed -ivssed -i '') - •Test scripts on all target platforms (Linux, macOS, BSD variants)
- •Document minimum version requirements in script header comments
- •Provide fallback implementations for platform-specific features
- •Use built-in Bash features over external commands when possible for portability
- •Avoid bashisms when POSIX compliance is required, document when using Bash-specific features
Readability & Maintainability
- •Use long-form options in scripts for clarity:
--verboseinstead of-v - •Employ consistent naming: snake_case for functions/variables, UPPER_CASE for constants
- •Add section headers with comment blocks to organize related functions
- •Keep functions under 50 lines; refactor larger functions into smaller components
- •Group related functions together with descriptive section headers
- •Use descriptive function names that explain purpose:
validate_input_filenotcheck_file - •Add inline comments for non-obvious logic, avoid stating the obvious
- •Maintain consistent indentation (2 or 4 spaces, never tabs mixed with spaces)
- •Place opening braces on same line for consistency:
function_name() { - •Use blank lines to separate logical blocks within functions
- •Document function parameters and return values in header comments
- •Extract magic numbers and strings to named constants at top of script
Safety & Security Patterns
- •Declare constants with
readonlyto prevent accidental modification - •Use
localkeyword for all function variables to avoid polluting global scope - •Implement
timeoutfor external commands:timeout 30s curl ...prevents hangs - •Validate file permissions before operations:
[[ -r "$file" ]] || exit 1 - •Use process substitution
<(command)instead of temporary files when possible - •Sanitize user input before using in commands or file operations
- •Validate numeric input with pattern matching:
[[ $num =~ ^[0-9]+$ ]] - •Never use
evalon user input; use arrays for dynamic command construction - •Set restrictive umask for sensitive operations:
(umask 077; touch "$secure_file") - •Log security-relevant operations (authentication, privilege changes, file access)
- •Use
--to separate options from arguments:rm -rf -- "$user_input" - •Validate environment variables before using:
: "${REQUIRED_VAR:?not set}" - •Check exit codes of all security-critical operations explicitly
- •Use
trapto ensure cleanup happens even on abnormal exit
Performance Optimization
- •Avoid subshells in loops; use
while readinstead offor i in $(cat file) - •Use Bash built-ins over external commands:
[[ ]]instead oftest,${var//pattern/replacement}instead ofsed - •Batch operations instead of repeated single operations (e.g., one
sedwith multiple expressions) - •Use
mapfile/readarrayfor efficient array population from command output - •Avoid repeated command substitutions; store result in variable once
- •Use arithmetic expansion
$(( ))instead ofexprfor calculations - •Prefer
printfoverechofor formatted output (faster and more reliable) - •Use associative arrays for lookups instead of repeated grepping
- •Process files line-by-line for large files instead of loading entire file into memory
- •Use
xargs -Pfor parallel processing when operations are independent
Documentation Standards
- •Implement
--helpand-hflags showing usage, options, and examples - •Provide
--versionflag displaying script version and copyright information - •Include usage examples in help output for common use cases
- •Document all command-line options with descriptions of their purpose
- •List required vs optional arguments clearly in usage message
- •Document exit codes: 0 for success, 1 for general errors, specific codes for specific failures
- •Include prerequisites section listing required commands and versions
- •Add header comment block with script purpose, author, and modification date
- •Document environment variables the script uses or requires
- •Provide troubleshooting section in help for common issues
- •Generate documentation with
shdocfrom special comment formats - •Create man pages using
shellmanfor system integration - •Include architecture diagrams using Mermaid or GraphViz for complex scripts
Modern Bash Features (5.x)
- •Bash 5.0: Associative array improvements,
${var@U}uppercase conversion,${var@L}lowercase - •Bash 5.1: Enhanced
${parameter@operator}transformations,compatshopt options for compatibility - •Bash 5.2:
varredir_closeoption, improvedexecerror handling,EPOCHREALTIMEmicrosecond precision - •Check version before using modern features:
[[ ${BASH_VERSINFO[0]} -ge 5 && ${BASH_VERSINFO[1]} -ge 2 ]] - •Use
${parameter@Q}for shell-quoted output (Bash 4.4+) - •Use
${parameter@E}for escape sequence expansion (Bash 4.4+) - •Use
${parameter@P}for prompt expansion (Bash 4.4+) - •Use
${parameter@A}for assignment format (Bash 4.4+) - •Employ
wait -nto wait for any background job (Bash 4.3+) - •Use
mapfile -d delimfor custom delimiters (Bash 4.4+)
CI/CD Integration
- •GitHub Actions: Use
shellcheck-problem-matchersfor inline annotations - •Pre-commit hooks: Configure
.pre-commit-config.yamlwithshellcheck,shfmt,checkbashisms - •Matrix testing: Test across Bash 4.4, 5.0, 5.1, 5.2 on Linux and macOS
- •Container testing: Use official bash:5.2 Docker images for reproducible tests
- •CodeQL: Enable shell script scanning for security vulnerabilities
- •Actionlint: Validate GitHub Actions workflow files that use shell scripts
- •Automated releases: Tag versions and generate changelogs automatically
- •Coverage reporting: Track test coverage and fail on regressions
- •Example workflow:
shellcheck *.sh && shfmt -d *.sh && bats test/
Security Scanning & Hardening
- •SAST: Integrate Semgrep with custom rules for shell-specific vulnerabilities
- •Secrets detection: Use
gitleaksortrufflehogto prevent credential leaks - •Supply chain: Verify checksums of sourced external scripts
- •Sandboxing: Run untrusted scripts in containers with restricted privileges
- •SBOM: Document dependencies and external tools for compliance
- •Security linting: Use ShellCheck with security-focused rules enabled
- •Privilege analysis: Audit scripts for unnecessary root/sudo requirements
- •Input sanitization: Validate all external inputs against allowlists
- •Audit logging: Log all security-relevant operations to syslog
- •Container security: Scan script execution environments for vulnerabilities
Observability & Logging
- •Structured logging: Output JSON for log aggregation systems
- •Log levels: Implement DEBUG, INFO, WARN, ERROR with configurable verbosity
- •Syslog integration: Use
loggercommand for system log integration - •Distributed tracing: Add trace IDs for multi-script workflow correlation
- •Metrics export: Output Prometheus-format metrics for monitoring
- •Error context: Include stack traces, environment info in error logs
- •Log rotation: Configure log file rotation for long-running scripts
- •Performance metrics: Track execution time, resource usage, external call latency
- •Example:
log_info() { logger -t "$SCRIPT_NAME" -p user.info "$*"; echo "[INFO] $*" >&2; }
Quality Checklist
- •Scripts pass ShellCheck static analysis with minimal suppressions
- •Code is formatted consistently with shfmt using standard options
- •Comprehensive test coverage with Bats including edge cases
- •All variable expansions are properly quoted
- •Error handling covers all failure modes with meaningful messages
- •Temporary resources are cleaned up properly with EXIT traps
- •Scripts support
--helpand provide clear usage information - •Input validation prevents injection attacks and handles edge cases
- •Scripts are portable across target platforms (Linux, macOS)
- •Performance is adequate for expected workloads and data sizes
Output
- •Production-ready Bash scripts with defensive programming practices
- •Comprehensive test suites using bats-core or shellspec with TAP output
- •CI/CD pipeline configurations (GitHub Actions, GitLab CI) for automated testing
- •Documentation generated with shdoc and man pages with shellman
- •Structured project layout with reusable library functions and dependency management
- •Static analysis configuration files (.shellcheckrc, .shfmt.toml, .editorconfig)
- •Performance benchmarks and profiling reports for critical workflows
- •Security review with SAST, secrets scanning, and vulnerability reports
- •Debugging utilities with trace modes, structured logging, and observability
- •Migration guides for Bash 3→5 upgrades and legacy modernization
- •Package distribution configurations (Homebrew formulas, deb/rpm specs)
- •Container images for reproducible execution environments
Essential Tools
Static Analysis & Formatting
- •ShellCheck: Static analyzer with
enable=allandexternal-sources=trueconfiguration - •shfmt: Shell script formatter with standard config (
-i 2 -ci -bn -sr -kp) - •checkbashisms: Detect bash-specific constructs for portability analysis
- •Semgrep: SAST with custom rules for shell-specific security issues
- •CodeQL: GitHub's security scanning for shell scripts
Testing Frameworks
- •bats-core: Maintained fork of Bats with modern features and active development
- •shellspec: BDD-style testing framework with rich assertions and mocking
- •shunit2: xUnit-style testing framework for shell scripts
- •bashing: Testing framework with mocking support and test isolation
Modern Development Tools
- •bashly: CLI framework generator for building command-line applications
- •basher: Bash package manager for dependency management
- •bpkg: Alternative bash package manager with npm-like interface
- •shdoc: Generate markdown documentation from shell script comments
- •shellman: Generate man pages from shell scripts
CI/CD & Automation
- •pre-commit: Multi-language pre-commit hook framework
- •actionlint: GitHub Actions workflow linter
- •gitleaks: Secrets scanning to prevent credential leaks
- •Makefile: Automation for lint, format, test, and release workflows
Common Pitfalls to Avoid
- •
for f in $(ls ...)causing word splitting/globbing bugs (usefind -print0 | while IFS= read -r -d '' f; do ...; done) - •Unquoted variable expansions leading to unexpected behavior
- •Relying on
set -ewithout proper error trapping in complex flows - •Using
echofor data output (preferprintffor reliability) - •Missing cleanup traps for temporary files and directories
- •Unsafe array population (use
readarray/mapfileinstead of command substitution) - •Ignoring binary-safe file handling (always consider NUL separators for filenames)
Dependency Management
- •Package managers: Use
basherorbpkgfor installing shell script dependencies - •Vendoring: Copy dependencies into project for reproducible builds
- •Lock files: Document exact versions of dependencies used
- •Checksum verification: Verify integrity of sourced external scripts
- •Version pinning: Lock dependencies to specific versions to prevent breaking changes
- •Dependency isolation: Use separate directories for different dependency sets
- •Update automation: Automate dependency updates with Dependabot or Renovate
- •Security scanning: Scan dependencies for known vulnerabilities
- •Example:
basher install username/repo@versionorbpkg install username/repo -g
Advanced Techniques
- •Error Context: Use
trap 'echo "Error at line $LINENO: exit $?" >&2' ERRfor debugging - •Safe Temp Handling:
trap 'rm -rf "$tmpdir"' EXIT; tmpdir=$(mktemp -d) - •Version Checking:
(( BASH_VERSINFO[0] >= 5 ))before using modern features - •Binary-Safe Arrays:
readarray -d '' files < <(find . -print0) - •Function Returns: Use
declare -g resultfor returning complex data from functions - •Associative Arrays:
declare -A config=([host]="localhost" [port]="8080")for complex data structures - •Parameter Expansion:
${filename%.sh}remove extension,${path##*/}basename,${text//old/new}replace all - •Signal Handling:
trap cleanup_function SIGHUP SIGINT SIGTERMfor graceful shutdown - •Command Grouping:
{ cmd1; cmd2; } > output.logshare redirection,( cd dir && cmd )use subshell for isolation - •Co-processes:
coproc proc { cmd; }; echo "data" >&"${proc[1]}"; read -u "${proc[0]}" resultfor bidirectional pipes - •Here-documents:
cat <<-'EOF'with-strips leading tabs, quotes prevent expansion - •Process Management:
wait $pidto wait for background job,jobs -plist background PIDs - •Conditional Execution:
cmd1 && cmd2run cmd2 only if cmd1 succeeds,cmd1 || cmd2run cmd2 if cmd1 fails - •Brace Expansion:
touch file{1..10}.txtcreates multiple files efficiently - •Nameref Variables:
declare -n ref=varnamecreates reference to another variable (Bash 4.3+) - •Improved Error Trapping:
set -Eeuo pipefail; shopt -s inherit_errexitfor comprehensive error handling - •Parallel Execution:
xargs -P $(nproc) -n 1 commandfor parallel processing with CPU core count - •Structured Output:
jq -n --arg key "$value" '{key: $key}'for JSON generation - •Performance Profiling: Use
time -vfor detailed resource usage orTIMEFORMATfor custom timing
References & Further Reading
Style Guides & Best Practices
- •Google Shell Style Guide - Comprehensive style guide covering quoting, arrays, and when to use shell
- •Bash Pitfalls - Catalog of common Bash mistakes and how to avoid them
- •Bash Hackers Wiki - Comprehensive Bash documentation and advanced techniques
- •Defensive BASH Programming - Modern defensive programming patterns
Tools & Frameworks
- •ShellCheck - Static analysis tool and extensive wiki documentation
- •shfmt - Shell script formatter with detailed flag documentation
- •bats-core - Maintained Bash testing framework
- •shellspec - BDD-style testing framework for shell scripts
- •bashly - Modern Bash CLI framework generator
- •shdoc - Documentation generator for shell scripts
Security & Advanced Topics
- •Bash Security Best Practices - Security-focused shell script patterns
- •Awesome Bash - Curated list of Bash resources and tools
- •Pure Bash Bible - Collection of pure bash alternatives to external commands