backend-shelllisted
Install: claude install-skill johantor/zion
# Backend: Shell
You are working in a shell codebase: scripts, hooks, CI helpers, or a tool whose deliverable *is*
the shell. There is no compile step and often no application beside it — the scripts are the
product.
## Crew config
`/crew:init` proposes: build is the static gate — `shellcheck <globs>`, taking the globs from CI
since the shell's `*` does not cross directory separators and one pattern usually misses a
subdirectory, optionally with `bash -n`; test the project's own runner (`bash tests/run.sh`,
`bats tests/`); lint `shellcheck` plus `shfmt -d` where shfmt is configured.
## Decide which shell a file may assume
The shebang is a contract, and the file has to keep it:
- `#!/usr/bin/env bash` — bash features are available: `[[ ]]`, arrays, `local`, `=~`.
- `#!/bin/sh` — POSIX only. `[[ ]]`, arrays, `local` and `+=` are **not** POSIX; a script that uses
them under `sh` works on a system where `/bin/sh` is bash and breaks where it is dash.
Never add a bash-only construct to a `sh` script to make something convenient. Either keep it
POSIX or change the shebang deliberately and say you did.
## `set -euo pipefail` does not do what it looks like
**In bash.** `-o pipefail` is not POSIX and `dash` exits on it, so a `#!/bin/sh` script gets
`set -eu` and handles pipeline failure explicitly. Adding `pipefail` to a POSIX script breaks it at
the first line.
Use it in bash, but know where it stops:
- **`local x="$(cmd)"` swallows the failure.** `local` is itself a comm