Safe, robust Bash script: error handling, locking, logs and dry-run
Generate a server-ready Bash script: strict mode, trap cleanup, getopts argument parsing, a lock against concurrent runs, logging, dry-run mode and ShellCheck-clean code. Designed for ChatGPT, Claude, Gemini and Microsoft Copilot. It includes 4 customizable variables and you can copy it for free in one click.
Intermediate · Code · Pending editorial review
Prompt
Act as a Linux systems administrator who writes maintainable, safe shell scripts.
I need a script that does the following: {{task}}
- Environment it will run in: {{environment}}
- Inputs (arguments, files, variables): {{inputs}}
- What it modifies or deletes: {{effects}}
Deliverables:
1. The complete script with:
- A shebang suited to the environment and strict mode (`set -Eeuo pipefail`) or its equivalent if the shell is not Bash, explaining its gotchas.
- A `usage` function and argument parsing with `getopts`, including `-h`, `-v` (verbose) and `-n` (dry-run).
- A dependency check with `command -v` and clear messages when something is missing.
- Variables always quoted, `local` inside functions and no `eval`.
- Temp files via `mktemp` and cleanup with `trap` on `EXIT`, `INT` and `TERM`.
- A lock with `flock` (or a portable alternative) to prevent two simultaneous runs.
- Timestamped logs to stderr and optionally to a file.
- Documented exit codes.
- In dry-run mode, print what it would do without running anything destructive.
2. An explanation of each block and of any dangerous line (deletions, permissions, `sudo`).
3. How to verify it: ShellCheck with no warnings, plus a few bats-core tests or a manual procedure in a scratch directory.
4. How to schedule it with cron or a systemd timer if that makes sense, including the PATH and variables it needs.
Constraints:
- Any `rm` or overwrite must first check that the path is not empty and not `/`.
- Do not invent paths or server names: use mine or [FILL IN].
- If the task is ambiguous or dangerous, ask me before writing the script.
- Recommend testing with `-n` first and outside production.How to use it
- Describe the task step by step the way you would do it by hand.
- Name the exact system (distro, macOS or container) because it changes the available shell.
- Run ShellCheck, execute with
-nand review the output before dropping dry-run.
Usage example
Task: compress logs older than 7 days in /var/log/myapp and delete ones older than 30 · Environment: Ubuntu 24.04 with Bash 5 · Effects: deletes old files.
Sample output
1. Script
#!/usr/bin/env bash
# rotate-logs.sh — compress .log older than N days, delete .gz older than M days
set -Eeuo pipefail
LOG_DIR="/var/log/myapp"; COMPRESS_DAYS=7; DELETE_DAYS=30
DRY_RUN=0; VERBOSE=0; LOCK="/run/lock/rotate-logs.lock"
log() { printf '%s [%s] %s\n' "$(date '+%F %T')" "$1" "$2" >&2; }
usage() { echo "Usage: ${0##*/} [-h] [-v] [-n] [-d dir] [-c days] [-r days]"; }
run() { if (( DRY_RUN )); then log DRY "$*"; return 0; fi
if (( VERBOSE )); then log INFO "$*"; fi; "$@"; }
while getopts ":hvnd:c:r:" opt; do
case "$opt" in
h) usage; exit 0 ;; v) VERBOSE=1 ;; n) DRY_RUN=1 ;;
d) LOG_DIR="$OPTARG" ;; c) COMPRESS_DAYS="$OPTARG" ;; r) DELETE_DAYS="$OPTARG" ;;
*) usage; exit 1 ;;
esac
done
# Never operate on an empty path or on /
[[ -n "$LOG_DIR" && "$LOG_DIR" != "/" && -d "$LOG_DIR" ]] || { log ERROR "invalid directory: $LOG_DIR"; exit 2; }
[[ "$COMPRESS_DAYS$DELETE_DAYS" =~ ^[0-9]+$ ]] || { log ERROR "days must be integers"; exit 1; }
command -v gzip >/dev/null || { log ERROR "gzip is missing"; exit 3; }
exec 9>"$LOCK"; flock -n 9 || { log WARN "another run is in progress"; exit 4; }
find "$LOG_DIR" -type f -name '*.log' -mtime +"$COMPRESS_DAYS" -print0 |
while IFS= read -r -d '' f; do run gzip -- "$f"; done
find "$LOG_DIR" -type f -name '*.gz' -mtime +"$DELETE_DAYS" -print0 |
while IFS= read -r -d '' f; do run rm -f -- "$f"; done
-print0 with read -d '' handles file names with spaces, and -- stops a file starting with a dash from being read as an option. Run ./rotate-logs.sh -n -v first and put it through ShellCheck…
Key facts
- Category
- Programming & development · Automations
- Output type
- Code
- Level
- Intermediate
- Designed for
- ChatGPT, Claude, Gemini and Microsoft Copilot
- Verified in
- Pending editorial verification
- Variables
- Task, Environment, Inputs and What it modifies or deletes
- Language
- English
- Price
- Free, no sign-up
- Updated
- Nov 7, 2026
Frequently asked questions
What exactly does set -Eeuo pipefail do?
It stops the script on an error (-e), on unset variables (-u) and when any command in a pipeline fails (pipefail); -E passes the ERR trap into functions. It has exceptions, which is why the prompt asks for them to be explained.
Why use flock in a scheduled script?
It prevents two runs from overlapping when the previous one has not finished yet, which is common with cron. Without a lock, two copies can clobber each other's files or duplicate work.
What is this prompt for?
Generate a server-ready Bash script: strict mode, trap cleanup, getopts argument parsing, a lock against concurrent runs, logging, dry-run mode and ShellCheck-clean code.
Which AI tools does it work with?
It is designed for ChatGPT, Claude, Gemini and Microsoft Copilot. We have not verified it in these tools yet, so results may vary between them.
How do I customize the prompt?
Click “Customize” and fill in the variables (Task, Environment, Inputs and What it modifies or deletes). The text updates instantly and you can then copy it in one click. Values are stored only in your browser.
Do I need experience to use it?
It is intermediate: it helps to know the topic so you can provide good context and review the result critically.
Is this prompt free?
Yes. Every HomeCasa Prompts prompt is free, with no sign-up or subscription. You can also use them in professional projects.
Can I trust the AI output?
Treat it as a high-quality draft: always check data, figures and important claims before publishing or making decisions.