writing-shell · git:20260602.5ac56fc · 2026-06-02 · sha256 0764eed1fed3f5d2
writing-shell git:20260602.5ac56fcC
Immutable. This exact content is served forever at /api/v1/blob/0764eed1fed3f5d2.
--- description: Idiomatic shell development for POSIX sh, Bash, Zsh, Fish, hooks, CI shell steps, and scriptable CLI glue. Use when writing or changing `.sh`, `.bash`, `.zsh`, `.fish`, `.bats`, shell functions, shell pipelines, or command-runner recipes. Emphasizes portability, quoting, safe filesystem/process handling, non-TUI CLI tools, ShellCheck, shfmt, Bats, and ShellSpec. NOT for Python, TypeScript, Go, web code, or infrastructure operations. name: writing-shell --- # Shell Development ## Scope - Use for shell scripts, hooks, CI shell blocks, command pipelines, and local automation glue. - Do not use for cloud, Kubernetes, Terraform, host, or network operations; use `operating-infra`. - Do not use for application logic that belongs in Python, Go, TypeScript, or another project language. ## Read references - Read [patterns.md](references/patterns.md) before non-trivial scripts or pipelines. - Read [tools.md](references/tools.md) when choosing external CLI tools or parsing structured data. - Read [testing.md](references/testing.md) before adding or changing shell tests or quality gates. ## Defaults - Follow the existing shebang, shell, style, and project tooling first. - For new portable scripts, use POSIX `sh` when the logic is simple; use Bash when arrays, `pipefail`, regex, or richer functions are needed. - Use Zsh or Fish only for existing files or explicit user intent. Keep Fish/Zsh config separate from portable scripts. - Do not rely on the agent's current shell. Put the intended shell in the shebang or invoke it explicitly in tests. - Prefer small shell scripts that call stable tools. Move complex data modeling or business logic to a real language. ## Core rules - Quote expansions unless word splitting is intentional and documented by structure. - Avoid `eval`, `curl | sh`, parsing `ls`, unguarded globbing, and unsafe `rm`/`mv`/`cp` paths. - Use arrays for arguments in Bash; use newline/NUL-safe loops for filenames. - Use `mktemp` plus cleanup traps for temporary files and directories. - Check required external commands when a script depends on them. Do not install tools silently. - Account for macOS/BSD versus GNU flag differences when writing portable scripts. - Prefer machine-readable output from tools, then parse it with structured parsers. - Use `looking-up-docs` for exact external CLI flags, syntax, or version behavior; do not guess from memory. ## Verification Run the project-configured shell gates. Prefer: - formatting: `shfmt` - linting: `shellcheck`; `checkbashisms` for POSIX `sh` - tests: Bats for Bash-heavy projects; ShellSpec for POSIX or multi-shell behavior - security/policy: Semgrep shell rules when the script handles secrets, downloads, deletion, or user-controlled input If a tool is unavailable or unconfigured, state the gap and run the closest available check. If a check fails, quote the diagnostic, fix the cause, and rerun the relevant check. ## Final response Include: - changed files - shell target used: POSIX sh, Bash, Zsh, or Fish - checks run and results - checks skipped with reasons - remaining portability or safety risks