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]+$ ]]