bash-script-builder
Generiert produktionsreife Bash-Skripte mit set -euo pipefail, Lint-Self-Check (shellcheck wenn vorhanden), strukturierter Doku und Verifikations-Snippet. Trigger bei jeder neuen Automatisierung (cron
SKILL.mdskills/bash-script-builder/SKILL.md
GitHubbash-script-builder
Standardvorlage für jedes Bash-Skript, das MaxClaw schreibt. Erzwingt robuste Defaults, sodass Skripte auch im 03:00-Cron nicht stillschweigend fehlschlagen.
When to use
- Jedes Mal, wenn MaxClaw ein neues
.shschreibt. - Beim Refactor von Alt-Skripten ohne
set -euo pipefail. - Für Cron-Helper, die mit
openclaw cron createregistriert werden sollen.
Pattern
1. Boilerplate-Generator (scripts/new-bash-script.sh)
#!/usr/bin/env bash
# new-bash-script.sh — generiert Skript-Boilerplate
set -euo pipefail
NAME="${1:?usage: new-bash-script.sh <name>}"
TARGET="${2:-./$NAME.sh}"
cat > "$TARGET" <<'BASH'
#!/usr/bin/env bash
# =============================================================================
# NAME_PLACEHOLDER — Kurzbeschreibung (TODO anpassen)
# Erzeugt: $(date +%Y-%m-%d) durch maxclaw bash-script-builder
# Aufruf: NAME_PLACEHOLDER [argumente]
# =============================================================================
set -euo pipefail
# --- Pfade / Konstanten -----------------------------------------------------
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LOG_DIR="${LOG_DIR:-$HOME/.local/share/maxclaw/logs}"
mkdir -p "$LOG_DIR"
# --- Logging -----------------------------------------------------------------
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; NC='\033[0m'
ts() { date +%Y-%m-%dT%H:%M:%S%z; }
info() { echo -e "${GREEN}[$(ts)] →${NC} $*"; }
warn() { echo -e "${YELLOW}[$(ts)] ⚠${NC} $*" >&2; }
err() { echo -e "${RED}[$(ts)] ✗${NC} $*" >&2; }
log() { echo "[$(ts)] $*" >> "$LOG_DIR/NAME_PLACEHOLDER.log"; }
# --- Argumente ---------------------------------------------------------------
usage() {
cat <<USG
Usage: $(basename "$0") [--dry-run] [-h]
--dry-run Nur anzeigen, nichts ausführen
-h, --help Diese Hilfe
USG
}
DRY_RUN=0
while [[ $# -gt 0 ]]; do
case "$1" in
--dry-run) DRY_RUN=1; shift ;;
-h|--help) usage; exit 0 ;;
*) err "unbekanntes Argument: $1"; usage; exit 2 ;;
esac
done
# --- Hauptlogik (TODO) -------------------------------------------------------
main() {
info "starte NAME_PLACEHOLDER (dry-run=$DRY_RUN)"
# TODO: Implementierung
}
# --- Trap für sauberes Beenden -----------------------------------------------
trap 'err "abgebrochen in Zeile $LINENO"' ERR INT TERM
main "$@"
BASH
# NAME ersetzen (nicht in Heredoc möglich → sed)
sed -i "s/NAME_PLACEHOLDER/$NAME/g" "$TARGET"
chmod +x "$TARGET"
info "erzeugt: $TARGET"
2. Lint-Snippet (jedes neue Skript sollte das können)
# In CI / Pre-Commit:
shellcheck -x "$TARGET" || warn "shellcheck nicht OK — bitte prüfen"
bash -n "$TARGET" || { err "Syntax-Fehler"; exit 1; }
3. Doku-Generator (scripts/doc-gen.sh)
#!/usr/bin/env bash
# doc-gen.sh — extrahiert usage-Block + Header → Markdown
set -euo pipefail
SCRIPT="${1:?script}"
NAME="$(basename "$SCRIPT" .sh)"
HEADER="$(sed -n '/^# ====/,/^# ====/p' "$SCRIPT" | sed '/=====/d')"
USAGE="$(sed -n '/^usage()/,/^}/p' "$SCRIPT" | sed '1d;$d')"
cat <<MD
# $NAME
$HEADER
## Usage
\`\`\`
$USAGE
\`\`\`
MD
Pitfalls
- ❌
set -eohne-o pipefail→ Pipes ignorieren Fehler der linken Seite (klassischer Cron-Killer:grep foo file | wc -list 0 statt Fehler). - ❌
$VARohne Quotes — bei Pfaden mit Spaces/Globs → Wort-Splitting + Globbing. Immer"$VAR". - ❌
cd $DIRohne Schutz — wenn Verzeichnis fehlt, landet man im $HOME und überschreibt dort.cd "$DIR" || exit 1oderpushd. - ❌
trap ERRfängt keine Command-Substitution-Fehler — dafürset -Ezusätzlich. - ✅
BASH_SOURCE[0]statt$0— bleibt korrekt beisource/Symlinks. - ✅
printf '%s\n'stattechofür variable Daten (kein Backslash-Issue).
Cron-Beispiel
# Generator-Aufruf im Workflow, kein Cron nötig (manueller Trigger)