Regeln, Standards, Kontextstruktur und Werkzeuge übernommen; 2nd-brain- Inhalte (Stacks, Ansible-Inventar, Architektur, Knowledge) entfernt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
8.8 KiB
Bash-Standard (verbindlich)
Gilt für jedes Bash-Script dieser Basis und ihrer Projekte. Referenzimplementierung:
templates/bash/. Die Scripts inbin/sind nach diesem Standard gebaut und dienen als Beispiele.
1. Bausteine – drei Dateien, mehr nicht
<scriptdir>/
├── mein_script.sh # Präambel (= Hilfe) + Bootstrap + Funktionen + main
├── _functions.sh # gemeinsame Basis – Kopie aus templates/bash/, NICHT lokal ändern
├── _functions.local.sh # optional: projektspezifische Funktionen (lädt _functions.sh automatisch)
├── .env # optional: Einstellungen (nie im Git)
└── .env.example # Pflicht, wenn .env genutzt wird: gleiche Schlüssel, Platzhalter
Mehrere Scripts in einem Verzeichnis teilen sich _functions.sh und .env.
Das frühere Modell (_global_functions.sh, _project_functions.sh, _project_settings.sh) entfällt:
Settings → .env, Projektfunktionen → _functions.local.sh.
2. Aufbau eines Scripts
#!/usr/bin/env bash
#-------------------------------------------------------------------------------
## @file backup_db.sh
## @brief Sichert die Datenbank nach $DIR_BACKUP
## @author <Name aus ai/context/responsible.md>
## @owner <Name/Rolle aus ai/context/responsible.md>
## @assist KI-unterstützt (<Modell>), geprüft von <author>
## @version 1.0.0 (07.10.2026)
##
## @usage backup_db.sh [Optionen] <datenbank>
## @options
## @OPTIONS@
## @env .env neben dem Script (Vorlage: .env.example)
## @exit 0 = ok · 1 = Fehler · 2 = Aufruffehler
#-------------------------------------------------------------------------------
set -Eeuo pipefail
SCRIPT_PATH="$(readlink -f -- "${BASH_SOURCE[0]}")" # Bootstrap – unverändert übernehmen
SCRIPT_DIR="${SCRIPT_PATH%/*}"
SCRIPT_NAME="${SCRIPT_PATH##*/}"
source "${SCRIPT_DIR}/_functions.sh" || { echo "FEHLER: ${SCRIPT_DIR}/_functions.sh fehlt" >&2; exit 1; }
B_OPTS+=( "k|keep|value:TAGE|14|Sicherungen so lange behalten" )
b_init "$@"
set -- "${ARGS[@]}"
## @brief Hauptablauf
## @param $1 Datenbankname
## @return 0 ok, 1 Fehler
main() { … }
main "$@"
Präambel = Hilfe = Doku
- Der Header zwischen den ersten beiden
#------Linien ist gleichzeitig die Hilfe (-h):b_usagegibt alle##-Zeilen ohne##aus. ## @OPTIONS@wird durch die Optionsliste ausB_OPTSersetzt → Hilfe und Optionen können nicht auseinanderlaufen.##ist der Doku-Marker (wie/**bei javadoc).bin/bashdoc.sh script.sherzeugt daraus Markdown. Normale Kommentare mit#.- Header-Pflichtfelder:
rules/headers.md.
3. Pfadsicherheit
| Variable | Inhalt |
|---|---|
SCRIPT_PATH |
absoluter, aufgelöster Pfad des Scripts (Symlinks aufgelöst) |
SCRIPT_DIR |
Verzeichnis des Scripts – Basis für .env, _functions.sh, relative Pfade aus .env |
SCRIPT_NAME |
Dateiname des Scripts |
B_CALL_DIR |
$PWD beim Aufruf – Basis für relative Pfade von der Kommandozeile |
B_LIB_DIR |
Verzeichnis von _functions.sh |
B_TMP_DIR |
Temp-Verzeichnis nach b_tmpdir, wird beim Exit gelöscht |
- Nie
cdals Voraussetzung, nie relative Pfade ohne Basis. Helfer:b_abspath <pfad> [basis](Default-BasisSCRIPT_DIR). - Faustregel: Pfade aus
.env/Defaults → relativ zuSCRIPT_DIR; Pfade, die der Benutzer tippt → relativ zuB_CALL_DIR.
4. Optionen (B_OPTS)
Format je Eintrag: "kurz|lang|typ[:META]|default|Beschreibung" – typ = flag (0/1) oder value.
| Quelle | Wo | Hinweis |
|---|---|---|
Standard (-h -d -q -n -l) |
_functions.sh (B_OPTS_STD) |
immer da |
| Script-eigen | im Script vor b_init: B_OPTS+=(…) |
Regelfall |
| Verzeichnisweit | .env: B_OPTS+=(…) |
gilt für alle Scripts des Verzeichnisses |
- Ergebnis: Variable
OPTION_<LANG>(Großbuchstaben,-→_):--dry-run→OPTION_DRY_RUN,--keep 7→OPTION_KEEP=7. - Unterstützt:
-d,-dn(gebündelt),-l datei,-ldatei,--logfile datei,--logfile=datei,--debug=0,--(Ende der Optionen). Positionsargumente landen inARGS(auch zwischen Optionen). - Unbekannte Option / fehlender Wert → Meldung, Hinweis auf
--help, Exit 2. - Immer
+=verwenden, nieB_OPTS=(…)(würde Einträge aus.env/_functions.local.shlöschen). Kein|in Default/Text.
Vorrang (und Gültigkeit von Umgebungsvariablen)
Default < .env < Umgebung < Kommandozeile
- Exportierte
B_*/OPTION_*-Variablen aus der Umgebung werden vor dem Laden von.envgesichert und danach wiederhergestellt (B_LOG_LEVEL=debug ./script.shgewinnt gegen.env). Nicht exportierte Shell-Variablen des Aufrufers sieht das Script ohnehin nicht. - Für eigene Projektwerte in
.envdasselbe Verhalten perVAR="${VAR:-default}". .envwird nicht automatisch exportiert. Werte, die Kindprozesse brauchen, explizitexportieren (Geheimnisse möglichst nicht).- Wirkung der Standardoptionen:
-d→B_LOG_LEVEL=debug,-q→B_LOG_CONSOLE=0,-l→B_LOG_FILE,-n→brunführt nichts aus.
5. Ausgabe & Logging – nie echo
| Funktion | Level | Ziel Konsole | Zweck |
|---|---|---|---|
becho "…" |
info | stdout, ohne Präfix | Ersatz für echo |
bdebug "…" |
debug | stderr, [DEBUG] |
Details, nur bei -d |
bwarn "…" |
warn | stderr, [WARN] |
Auffälliges, Lauf geht weiter |
berror "…" |
error | stderr, [FEHLER] |
Fehler melden (Funktion entscheidet über return) |
bdie "…" [rc] |
error | stderr | melden + beenden (rc 2 = Aufruffehler mit Hilfe-Hinweis) |
blog <level> "…" |
– | – | Basis aller obigen |
Steuerung (.env, Umgebung oder Option):
| Variable | Default | Bedeutung |
|---|---|---|
B_LOG_LEVEL |
info |
Mindestlevel Konsole (debug/info/warn/error) |
B_LOG_CONSOLE |
1 |
Konsole an/aus |
B_LOG_FILE |
leer | Logdatei; leer = keine |
B_LOG_FILE_LEVEL |
= B_LOG_LEVEL |
eigenes Mindestlevel für die Datei |
B_LOG_COLOR |
auto |
Farben nur auf Terminal |
Logdatei-Format: JJJJ-MM-TT hh:mm:ss LEVEL script.sh[PID] Text.
Ausnahme vom echo-Verbot: echte Daten-Ausgabe für Pipes (printf '%s\n' "$ergebnis") – Meldungen gehen nie auf stdout außer über becho.
6. Fehler, Return-Codes, Aufräumen
set -Eeuo pipefailist Pflicht.b_initsetzt Traps:EXIT(Aufräumen),ERR(meldet Befehl, Funktion, Zeile),INT/TERM(Exit 130/143 → EXIT-Trap).- Return-Code-Prinzip: Jede Funktion endet mit
return 0(ok),1(Fehler) oder2(falscher Aufruf); dokumentiert unter@return. Fehler meldet die Funktion selbst (berror) und gibt den Code zurück – der Aufrufer entscheidet (if f; then,f || return 1). - Ergebnisse über stdout (
x="$(f)") oder globale Variablen mit Präfix – nie über Exit-Codes > 2. - Aufräumen: Script definiert optional
cleanup() { … }– wird vom EXIT-Trap mit dem Exit-Code aufgerufen, auch bei Fehler/Abbruch. Temporäres immer überb_tmpdir($B_TMP_DIR), wird automatisch entfernt.
7. Funktionsdoku („briefly!“)
## @brief Was die Funktion tut – ein Satz
## @param $1 Bedeutung
## @param $@ restliche Argumente
## @return 0 ok, 1 Fehler; Ausgabe auf stdout (falls zutreffend)
name() {
- Direkt über der Funktion, keine Leerzeile dazwischen. Interne Helfer mit
_beginnen (bashdoc.shblendet sie ohne-paus). localfür alle Variablen in Funktionen.
8. Weitere Helfer aus _functions.sh
| Funktion | Zweck |
|---|---|
brun cmd args… |
ausführen bzw. bei -n nur anzeigen (kein eval, Argumente als Array) |
b_require prog… |
prüft, ob Programme vorhanden sind |
b_require_vars VAR… |
prüft, ob Variablen gesetzt sind |
b_tmpdir |
legt $B_TMP_DIR an |
b_abspath pfad [basis] |
absoluter Pfad |
b_usage |
Hilfe ausgeben |
9. Stil
- Bash ≥ 4.4. Shebang
#!/usr/bin/env bash. 2 Leerzeichen Einrückung. - Immer quoten (
"$var","${arr[@]}"),[[ ]]statt[ ],$(…)statt Backticks,printfstattecho -e. - Dateinamen: Kleinbuchstaben,
_als Trenner, Endung.sh; Hilfsdateien mit_-Präfix. - Variablen: Konstanten/Globale
GROSS, lokaleklein; PräfixB_/_B_/OPTION_ist für_functions.shreserviert. - Prüfen vor Abgabe:
bash -n,shellcheck -x,-h,-n, ein echter Lauf (lokal,rules/testing.md).
10. Neues Script in 4 Schritten
cp ai/common/templates/bash/{script_template.sh,_functions.sh,.env.example} <ziel>/(_functions.shnur, wenn noch nicht vorhanden).- Umbenennen, Header ausfüllen (Verantwortliche aus
responsible.md),B_OPTSanpassen. - Funktionen mit Kurz-Doku +
mainschreiben. - Testen (§ 9), ggf.
bin/bashdoc.shfür die Projektdoku.
Änderungsprotokoll
- 07.10.2026 – angelegt; Stack auf
.env+_functions.sh(+ optional_functions.local.sh) reduziert.