hermes

Write a robust shell script

Writes a portable shell script with strict mode, argument parsing, a dry-run flag, clear errors and idempotent steps. Use when automating a chore you will run more than once.

context

Shell scripts written in a hurry fail in predictable ways: an unset variable expands to an empty string and rm -rf hits the wrong directory, a failed command in a pipeline is ignored, a filename with a space splits in two, GNU-only flags break on macOS, and a second run duplicates what the first run did. The person needs a script they can run twice, read in a year, and trust in a dry run first.

task

Write a script for this goal, to run on :

  1. If the goal leaves out something that decides what gets deleted, overwritten or sent (which paths, which hosts, whether it needs root), ask up to 3 questions and stop. Otherwise state your assumptions and continue.
  2. Choose the strict-mode preamble for the shell:
  • bash: set -Eeuo pipefail, a trap that reports the failing line on ERR, and a cleanup trap on EXIT.
  • zsh: emulate -L zsh and setopt ERR_EXIT NO_UNSET PIPE_FAIL.
  • posix-sh: set -eu. Do not rely on pipefail, arrays, [[ ]], local or $'...'; check pipeline stages explicitly where failure matters.
  • powershell: a param() block with [CmdletBinding(SupportsShouldProcess)], Set-StrictMode -Version Latest and $ErrorActionPreference = 'Stop'; check $LASTEXITCODE after native commands.
  1. Parse arguments: -h/--help (usage to stdout, exit 0), long options, required values validated up front, unknown options rejected with usage on stderr and exit 2. In bash and zsh use a while/case loop so long options work; getopts handles only short ones.
  2. Add a dry-run mode (--dry-run, or -WhatIf in PowerShell) that prints every state-changing command, safely quoted, instead of running it. Route all side effects through one helper so dry run cannot miss one.
  3. Make each step idempotent: test before acting, use mkdir -p and ln -sfn, check before appending to a file, and write files to a temp file on the same filesystem and then move it into place.
  4. Fail clearly: check required tools with command -v at start-up, print errors to stderr with the script name and a fix, and use distinct non-zero exit codes for distinct failures.
  5. Check the script against ShellCheck (or PSScriptAnalyzer) rules in your head, and fix anything they would flag.
constraints
  • Quote every expansion. Use -- before user-supplied paths. Never parse ls; use find ... -print0 with while IFS= read -r -d '' (bash/zsh) or a glob loop.
  • Guard destructive commands against empty variables with ${VAR:?}, and never rm -rf a path built from unchecked input.
  • Portability for macOS and Linux: macOS ships bash 3.2 (no associative arrays, mapfile or ${var,,}) and BSD tools (sed -i '', no date -d, no grep -P, different stat flags). If target_os is any or macos, avoid these or branch on uname explicitly.
  • No secrets in the script, arguments or logs. Read them from the environment or a file with restricted permissions.
  • Never fetch remote code and execute it.
  • If the job is better done by an existing tool (rsync, a package manager, a cron entry), say so in one line, then write the script anyway.
output format

Assumptions

Bullets, or "None".

Script

One complete code block with a header comment: purpose, usage line, exit codes.

Usage

Two or three example invocations, including a dry run.

What it changes

Every file, directory, service or remote system it creates, modifies or deletes.

How to test it

Steps to try it safely: dry run first, then a throwaway directory or container.

Limitations

What it does not handle, one line each.

1 required value still a placeholder; the assistant will ask for it.

details

kind
Prompt: a task you run by name to get one finished thing back
domain
Software engineering
category
Implementation
level
Intermediate
made for
Software engineer, DevOps / platform engineer, Site reliability engineer
risk
read-only
version
v1.0.0 · incubating
reviewed
2026-10-02
works in
Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Antigravity, OpenCode, Windsurf, Zed, Continue, AGENTS.md, ChatGPT, claude.ai

Edit on GitHubReport a problem

use in

Hodios CLI
npx @hermes-hq/hodios install write-shell-script --target claude-code
Agent Skills
npx skills add hermes-hq/hodios-dist --skill write-shell-script -a claude-code
Add the Hodios marketplace (once)
claude plugin marketplace add hermes-hq/hodios-dist
Install the software-engineering plugin
claude plugin install hodios-software-engineering@hodios

The plugin brings every entry in this domain at once.

more in implementation

All of Implementation
PromptImplementation

Put a change behind a feature flag

Wraps new behaviour behind a feature flag with a safe default, a kill switch, tests for both paths and a cleanup ticket. Use when shipping a risky change incrementally.

add-feature-flag
PromptImplementation

Add low-power sleep modes

Adds sleep modes to battery firmware, gating clocks and peripherals, choosing wake sources and state retention, and backs the change with a current measurement plan and battery-life budget.

add-low-power-sleep-modes
PromptImplementation

Add rate limiting to an API

Adds rate limiting to API endpoints with a fitting algorithm, keys, per-tier limits, standard headers, 429 responses and tests. Use when protecting endpoints from abuse or overload.

add-rate-limiting
PromptImplementation

Add retries and timeouts to external calls

Adds timeouts, retries with exponential backoff and jitter, idempotency and a circuit breaker to calls to an external service, with tests that simulate failures.

add-retries-and-timeouts
PersonaImplementation

Angular engineer

Acts as a senior Angular engineer who builds with standalone components and services, uses signals or RxJS where each fits, enforces strict typing and keeps change detection efficient.

angular-engineer
PersonaImplementation

Backend engineer

Acts as a backend engineer focused on correct data handling, clear API contracts, explicit failure modes and services that are easy to operate. Use as a builder or reviewer persona for server code.

backend-engineer