From bash-expert
Expert bash/shell scripting across environments where Bash is available (Linux, macOS, Git Bash on Windows, WSL, containers). This is a Bash-focused skill - it does not provide PowerShell parity; on Windows the target is the Bash interpreter (Git Bash / WSL), not native PowerShell. PROACTIVELY activate for: (1) ANY bash/shell script task, (2) System automation, (3) DevOps/CI/CD scripts, (4) Build/deployment automation, (5) Script review/debugging, (6) Converting commands to scripts. Provides: Google Shell Style Guide compliance, ShellCheck validation, Bash portability across Linux/macOS/WSL/Git Bash/containers, POSIX compliance, security hardening, error handling, performance optimization, testing with BATS, and production-ready patterns. Ensures professional-grade, secure, portable Bash scripts every time.
How this skill is triggered — by the user, by Claude, or both
Slash command
/bash-expert:bash-masterThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill targets **Bash itself**, wherever Bash runs - Linux, macOS, WSL, Git Bash / MSYS2 on Windows, and Bash-based container images. It does not cover **native PowerShell**: a PowerShell script is a different language and should use `powershell-expert`. On Windows, `bash-expert` assumes the user is running Bash inside Git Bash, WSL, or a similar Bash environment, and addresses the MSYS pat...
This skill targets Bash itself, wherever Bash runs - Linux, macOS, WSL, Git Bash / MSYS2 on Windows, and Bash-based container images. It does not cover native PowerShell: a PowerShell script is a different language and should use powershell-expert. On Windows, bash-expert assumes the user is running Bash inside Git Bash, WSL, or a similar Bash environment, and addresses the MSYS path-translation quirks that result.
Project-level conventions (Windows backslashes in tool calls, documentation discipline, etc.) live in the agent body and the windows-path-expert plugin. This skill focuses on Bash content; do not duplicate that boilerplate here.
#!/usr/bin/env bash
set -euo pipefail # Exit on error, undefined vars, pipe failures
IFS=$'\n\t' # Safe word splitting
# Run shellcheck your_script.sh before deployment.
# Test on every target platform before production.
Bash-portability quick check:
# Linux/macOS: Full bash features
# Git Bash (Windows): Most features, some system calls missing (no systemd, /proc differs)
# WSL: Effectively Linux; /mnt/c for Windows filesystem
# Containers: Depends on base image - alpine ships /bin/sh, not bash
# POSIX mode: Use /bin/sh and avoid bashisms
Always activate for:
Do not use this skill for:
powershell-expert.cmd/.bat) scriptingEvery script should open with the safety preamble:
#!/usr/bin/env bash
set -e # Exit on any error
set -u # Exit on undefined variable
set -o pipefail # Catch failures mid-pipeline
set -E # Inherit ERR trap into functions
IFS=$'\n\t' # Avoid word splitting on spaces
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly SCRIPT_NAME="$(basename "${BASH_SOURCE[0]}")"
Need to run on any UNIX sh | #!/bin/sh, no [[ ]], no arrays, no process substitution |
|---|---|
| Modern Linux/macOS with Bash | #!/usr/bin/env bash, prefer [[ ]], arrays, regex |
| Alpine/minimal containers | Either install bash explicitly or write POSIX-compliant sh |
# Always quote expansions
process "$file_path" # correct
process $file_path # word-splitting bug
# Arrays
files=("file 1.txt" "file 2.txt")
process "${files[@]}" # each element kept separate
process "${files[*]}" # joined as one string - usually wrong
Run shellcheck on every script. Only disable warnings with a justification comment: # shellcheck disable=SC2086 reason: intentional word splitting.
See references/best_practices.md for the full quoting/style table and references/patterns_antipatterns.md for the common pitfalls.
Git Bash auto-converts Unix-style arguments to Windows paths. This is the largest single source of cross-platform Bash bugs on Windows.
# The conversion: /foo becomes C:/Program Files/Git/usr/foo
# Disable per-command:
MSYS_NO_PATHCONV=1 command /path/that/should/stay/unix
# Manual conversion
unix_path=$(cygpath -u "C:\Windows\System32")
win_path=$(cygpath -w "/c/Users/username")
# Detect Git Bash
if [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "mingw"* ]]; then
: # Git Bash
fi
case "${MSYSTEM:-}" in
MINGW64|MINGW32|MSYS) : ;; # MSYS2 / Git Bash environment
esac
# Flags that look like paths
command //e //s # double-slash to suppress conversion
command -e -s # or use dash-options
Full Git Bash + Windows path notes live in references/windows-git-bash-paths.md.
GNU coreutils, /proc, systemd integration. Detect via [[ "$OSTYPE" == "linux-gnu"* ]].
BSD utilities behave differently from GNU. Most common gotchas: sed -i '' (empty string required), date flags differ, readlink -f not available on stock macOS.
if command -v gsed >/dev/null; then SED=gsed; else SED=sed; fi
Effectively Linux. The Windows filesystem is mounted at /mnt/c/. Detect via grep -qi microsoft /proc/version.
Alpine images ship only /bin/sh (BusyBox). Write POSIX-compliant scripts or apk add bash. Container init quirks: PID 1 must reap children and handle signals. Detect via [ -f /.dockerenv ] or [ -n "$KUBERNETES_SERVICE_HOST" ].
detect_platform() {
case "$OSTYPE" in
linux-gnu*) echo "linux" ;;
darwin*) echo "macos" ;;
msys*|cygwin*) echo "windows" ;;
*) echo "unknown" ;;
esac
}
Full per-platform tables (BSD-vs-GNU coreutils flags, WSL networking, container init patterns) live in references/platform_specifics.md.
The full patterns - function design, error handling, input validation, argument parsing, logging - live in references/in-depth-patterns.md. The headline rules:
UPPER_CASE; locals lower_case; mark immutable values readonly.if ! cmd, ||, traps, or a central error_exit helper).getopts or a case-based argument parser; print usage and exit 1 on bad input.These each have dedicated sections in references/in-depth-patterns.md:
| Topic | What it covers |
|---|---|
| Security | Command-injection prevention, path-traversal guards, privilege management, secure temp files |
| Performance | Avoiding subshells, bash built-ins vs externals, process substitution, array ops |
| Testing | BATS unit tests, integration test patterns, CI/CD wiring |
| Debugging | set -x, PS4, conditional debug helpers, tracing and profiling |
| Advanced patterns | Safe config parsing, parallel processing, signal handling, retries with backoff |
Read that reference any time you need the canonical code template for one of those topics.
references/platform_specifics.md - Detailed platform differences and workaroundsreferences/best_practices.md - Comprehensive industry standards and guidelinesreferences/patterns_antipatterns.md - Common patterns and pitfalls with solutionsreferences/windows-git-bash-paths.md - Git Bash / MSYS path-translation referencereferences/in-depth-patterns.md - Function design, security, performance, testing, debugging, advanced patternsreferences/resources.md - Official docs, style guides, tooling, and learning linksA Bash script written with this skill should:
shellcheck with no warningsset -euo pipefail-h/--helptrap EXIT)# Pre-deployment checklist
shellcheck script.sh
bash -n script.sh
bats test/script.bats
./script.sh --help
DEBUG=true ./script.sh
checkbashisms script.sh to surface non-portable constructs.command -v tool to verify a required tool is installed.sed --version etc.).shellcheck -W SC2086).PATH - set PATH explicitly../script.sh >> /tmp/cron.log 2>&1.time.set -x to find slow steps.npx claudepluginhub thimslugga/thimslugga-cc-plugins --plugin bash-expertGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.