SH Style Guide
Scope Boundaries
- Use this skill when the task matches the trigger condition described in
description. - Do not use this skill when the primary task falls outside this skill's domain.
Use this skill to write and review POSIX sh scripts that run reliably across environments where Bash features are unavailable.
Trigger And Co-activation Reference
- If available, use
references/trigger-matrix.mdfor canonical co-activation rules. - If available, resolve style-guide activation from changed files with
python3 scripts/resolve_style_guides.py <changed-path>.... - If available, validate trigger matrix consistency with
python3 scripts/validate_trigger_matrix_sync.py.
Quality Gate Command Reference
- If available, use
references/quality-gate-command-matrix.mdfor CI check-only and local autofix mapping.
Quick Start Snippets
Portable script skeleton
#!/bin/sh
set -eu
SCRIPT_NAME=$(basename "$0")
TEMP_DIR=$(mktemp -d)
cleanup() {
rm -rf -- "$TEMP_DIR"
}
on_error() {
line_number="$1"
echo "$SCRIPT_NAME: failed at line $line_number" >&2
}
trap cleanup EXIT HUP INT TERM
trap 'on_error "$LINENO"' ERR
main() {
echo "temp dir: $TEMP_DIR"
}
main "$@"
Required environment variable check (no silent default)
: "${API_TOKEN:?API_TOKEN is required}"
: "${API_BASE_URL:?API_BASE_URL is required}"
POSIX-safe argument handling (no arrays)
run_curl() {
url="$1"
curl --fail --silent --show-error \
--header "Authorization: Bearer ${API_TOKEN}" \
"$url"
}
Bounded retry loop
MAX_ATTEMPTS=5
RETRY_DELAY_SECONDS=2
retry_command() {
attempt=1
while [ "$attempt" -le "$MAX_ATTEMPTS" ]; do
if "$@"; then
return 0
fi
if [ "$attempt" -eq "$MAX_ATTEMPTS" ]; then
echo "command failed after $MAX_ATTEMPTS attempts" >&2
return 1
fi
sleep "$RETRY_DELAY_SECONDS"
attempt=$((attempt + 1))
done
}
Safe line reading
while IFS= read -r line; do
printf 'line=%s\n' "$line"
done < "$input_file"
Portability And Readability
- Target POSIX syntax only; avoid Bash/Zsh-specific features.
- Use
set -eufor executable scripts. - Prefer small functions and clear
mainorchestration. - Use uppercase constants and lowercase local variables.
- Keep comments short and intent-focused.
Data Handling And Quoting
- Quote parameter expansion by default.
- Avoid
evalunless strictly required and heavily validated. - Replace magic numbers with named constants and explicit units.
- Use
--for destructive command path arguments. - Validate all external input before using it in commands.
Error Handling And Safety
- Return explicit non-zero status for expected failure modes.
- Use
trapfor cleanup and signal handling. - Handle failures intentionally; do not mask with
|| trueunless justified. - Fail startup when required configuration is missing.
- Let failures surface when root-cause fixing is required.
Testing And Verification
- Add shell tests (
shunit2or project equivalent) for core paths. - Cover edge cases: empty input, whitespace paths, missing env vars, timeout/retry exhaustion.
- Document manual verification for environment-dependent behavior.
- Verify idempotency for repeatable automation scripts.
CI Required Quality Gates (check-only)
- Run
shellcheck -s sh. - Run
shfmt -d -ln posix. - Run shell tests (
shunit2/project equivalent). - Reject hidden failure paths and implicit behavior.
Optional Autofix Commands (local)
- Run
shfmt -w -ln posix. - Apply safe lint fixes, then rerun check-only commands.