| name | shell-scripting |
| description | Apply when writing or reviewing Bash or POSIX shell scripts — automation, CI steps, deploy scripts, or any shell-based tooling. |
| license | MIT |
| version | 1.0.0 |
| tokens_target | 1500 |
| triggers | bash script, shell script, posix scripting |
| loads_after | |
| supersedes |
Sub-Skill: Bash / POSIX Scripting
Purpose: Prevent silent failures, portability bugs, and security holes in shell scripts by enforcing safe defaults, clean structure, and ShellCheck compliance.
Rules
Safety & Error Handling
Fail-fast header. Always begin every shell script with
set -euo pipefailso that unset variables, failed commands, and pipeline errors abort execution immediately. Reference: ERR-2026-021Trap cleanup. Always register a
trap 'cleanup' EXITfunction to remove temp files and release locks even when the script exits early due to an error.Meaningful exit codes. Always exit with a non-zero code that reflects the failure category (e.g.,
exit 1for usage errors,exit 2for dependency missing); never exit with0on failure.No eval. Never use
evalto construct or execute dynamic commands; prefer arrays or explicit argument lists to avoid injection vulnerabilities.
Variables & Quoting
Quote every variable. Always double-quote variable expansions (
"$var","$@") to prevent word-splitting and glob expansion on values containing spaces or special characters.Declare locals. Always declare variables inside functions with
localto prevent accidental global namespace pollution.Readonly constants. Use
readonlyfor values that must not change after assignment (e.g.,readonly SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)").
Portability & Compatibility
POSIX shebang. Always start scripts with
#!/usr/bin/env bash(or#!/bin/shfor strict POSIX); never rely on/bin/bashbeing present at a fixed path on all target systems.Portable syntax. Prefer POSIX-compatible constructs (
[ ]over[[ ]],$(...)over backticks) when the script must run under/bin/sh; use Bash-specific features only when the shebang explicitly targets Bash.ShellCheck clean. Ensure every script passes
shellcheck -S warningwith zero warnings before committing; treat ShellCheck output as mandatory, not advisory.
Structure & Maintainability
Use functions. Always decompose scripts longer than ~30 lines into named functions with a
mainentry point called at the bottom; avoid top-level imperative code scattered throughout the file.Argument parsing with getopts. Use
getoptsfor option parsing in scripts that accept flags; never parse$1,$2manually for flag-style arguments.Temp file handling. Always create temporary files with
mktempand store the path in a variable cleaned up by theEXITtrap; never hard-code paths like/tmp/myfile.
Logging & Idempotency
Structured logging. Use a
log()helper that prefixes output with a timestamp and level (INFO,WARN,ERROR) and routes errors to stderr (>&2); never mix diagnostic output into stdout used for data.Idempotent operations. Ensure scripts can be run multiple times without side effects — use guards like
[ -d "$dir" ] || mkdir -p "$dir"andcommand -v tool >/dev/null 2>&1 || install_toolbefore acting.Heredocs for multi-line strings. Prefer heredocs (
<<'EOF' ... EOF) over concatenatedechocalls for multi-line output or embedded config; use the quoted form (<<'EOF') to suppress variable expansion when the content is literal.
See also
skills/code-quality/SKILL.mdskills/error-log/SKILL.md