I kept getting shell scripts that looked fine and then nuked a directory because an unset variable expanded to empty and rm -rf "$DIR/" became rm -rf /. Adding set -e alone is a trap: it silently doesn't trigger inside pipelines or command substitutions.
What finally worked was making the prompt spell out the exact strict-mode preamble AND ban the patterns that defeat it, then require a trap for cleanup. I also make it quote every expansion and prefer [[ over [.
Does anyone have a good way to get it to handle the set -e + grep returns 1 gotcha without wrapping every line in || true?
Write a POSIX-friendly Bash 4+ script `{SCRIPT_NAME}.sh` that {GOAL}. Target Linux and macOS.
Safety contract (do all of these, do not skip any):
- Start with `#!/usr/bin/env bash` then `set -Eeuo pipefail` and `IFS=$'\n\t'`.
- Quote EVERY variable expansion: `"$var"`, `"${arr[@]}"`. Never leave an unquoted `$x`.
- Never `rm -rf` a path built from a variable without first asserting the variable is non-empty and not `/`.
- Use `[[ ... ]]` for tests, `$(...)` not backticks, and `local` for all function vars.
- Add `trap cleanup EXIT INT TERM` that removes any temp files created with `mktemp`.
- Parse flags with a `while getopts` or a `case` loop; provide `-h/--help` usage and exit 2 on bad usage.
- Preflight: check every required command exists (`command -v`), fail with a clear message if not.
- Print errors to stderr via a `die()` helper that logs and `exit 1`.
Explain in comments how you handle the `set -e` vs. `grep` (exit 1 = no match) gotcha for any command whose non-zero exit is expected. End with a short REVIEW listing each dangerous operation in the script and why it is now safe.