Ich betreibe einen Raspberry Pi (Debian 13 "Trixie", aarch64) als Heimprovisorium für:
Wenn dieser Pi stirbt, will ich nicht stundenlang neu konfigurieren. Also: tägliches rsync-Backup auf eine exFAT-Platte und ein möglichst Setup-Skript, das aus dem Backup einen funktionsgleichen zweiten Pi macht.
Ich habe zwei Scripte unten angehangen: Backup und Restore. Im folgenden werden diese Scripte beschrieben:
Der erste Backup-Lauf war 9,4 GB groß. Eine Analyse zeigte:
| Ordner | Größe | gehört ins Backup? |
|---|---|---|
/home/achim/.cache/ | 3,2 GB | ❌ Browser-, pip-, Thumbnail-Cache |
/home/achim/.npm/ | 1,3 GB | ❌ npm-Package-Cache |
**/node_modules/ | je nach Projekt | ❌ wird per npm ci installiert |
| Papierkorb | ? | ❌ |
| Summe Caches | ~4,5 GB | – |
| Rest (SSH-Keys, Config, Projekte, ...) | ~4,9 GB | ✅ muss rein |
Caches enthalten keine Konfiguration – sie sind das Ergebnis von Tool-Aufrufen. npm install --cache ist überflüssig, wenn man npm install ohnehin laufen lässt. Ähnlich .cache/: Browser-Cache, thumbnails, pip-Wheels – alles wird bei Bedarf automatisch neu erzeugt.
Ausgeschlossen werden daher:
--exclude='.cache/'
--exclude='.npm/'
--exclude='.local/share/Trash/'
--exclude='**/node_modules/'
--exclude='.cargo/registry/'
--exclude='.cargo/git/'
--exclude='.cache/pip/'
Das Backup schrumpft so von 9,4 GB auf ~4,9 GB – und enthält trotzdem alles, was für einen kompletten Restore nötig ist.
Das Skript liegt unter /home/achim/.openclaw/scripts/backup_home.sh und wird täglich um 5:30 per Cron ausgeführt (crontab -l).
Auszug aus dem rsync-Aufruf:
EXCLUDES=(
--exclude='.cache/'
--exclude='.npm/'
--exclude='.local/share/Trash/'
--exclude='**/node_modules/'
--exclude='.cargo/registry/'
--exclude='.cargo/git/'
--exclude='.cache/pip/'
)
rsync "${EXCLUDES[@]}" -rltD --no-perms --no-owner --no-group \
"$BACKUP_SRC/" "$BACKUP_DIR/"
Da die Zielpartition exFAT ist, werden Berechtigungen und Owner nicht mitgesichert – das ist für die reine Datenwiederherstellung auch nicht nötig.
Retention (Aufbewahrung):
Bonus: Jedes Backup enthält automatisch eine setup_new_pi.sh – damit ist das Wiederherstellen auf einem neuen Pi trivial.
# Backup-Quelle prüfen (exFAT-Platte)
ls /media/achim/raspibackup/achimshone_20260609/
# Dateien auf den neuen Pi kopieren
# Entweder direkt per rsync von der Platte nach /home/achim
# oder die Platte im Pi einstecken und kopieren
cp -a /media/achim/raspibackup/achimshome_20260609/* /home/achim/
Wichtig: Der Ziel-Pfad muss /home/achim/ sein – alle Tools und Dienste erwarten diesen Pfad.
cd /home/achim
sudo bash setup_new_pi.sh
Nach etwa 5–10 Minuten (abhängig von der Internetgeschwindigkeit) ist der Pi einsatzbereit. Das Setup-Skript erledigt automatisch:
Das Skript /home/achim/setup_new_pi.sh (wird bei jedem Backup mitgeneriert) arbeitet in 9 Phasen:
apt-get install -y \
build-essential cmake git curl wget ffmpeg \
python3 python3-pip python3-venv nginx \
tesseract-ocr tesseract-ocr-deu exfatprogs
Node.js 22.x wird von NodeSource installiert.
npm install -g openclaw clawhub
Himalaya ist ein statisches Binary. Die ARM64-Version wird von GitHub geladen:
curl -fsSL -o /tmp/himalaya.tar.gz \
"https://github.com/soywod/himalaya/releases/download/v1.2.0/himalaya-linux-aarch64-musl.tar.gz"
Meilisearch läuft als systemd-Service unter dem User achim. Das Binary (v1.43.0) wird von GitHub geholt:
curl -fsSL -o /tmp/meilisearch.gz \
"https://github.com/meilisearch/meilisearch/releases/download/v1.43.0/meilisearch-linux-aarch64.gz"
Der Service wird sofort gestartet und auf Autostart gelegt.
Zwei virtuelle Umgebungen werden aufgesetzt:
~/whisper_light/ – Faster-Whisper (Spracherkennung, base-Modell)~/imgocr/ – OpenCV + numpy (Zählerstand-OCR)Zusätzlich wird beem (Hive-Blockchain-Zugriff) systemweit installiert.
Ein Symlink verknüpft das Wiki-Inhaltsverzeichnis mit dem nginx-Document-Root:
ln -sf /home/achim/.openclaw/workspace/AchimsDaten/wiki_contents /var/www/html/wiki
Der Backup-Job wird in die crontab des Users achim eingetragen:
30 5 * * * /home/achim/.openclaw/scripts/backup_home.sh
Der Volltextindex für das Wiki wird über index_all_files.py neu aufgebaut.
Zum Schluss werden alle Dateien im Home-Verzeichnis an den User achim übergeben.
Das Backup sichert Daten (Dateien, Konfigurationen, SSH-Keys, Wiki-Inhalte), aber nicht den Systemzustand (installierte Pakete, laufende Dienste). Das ist auch gut so – denn der Systemzustand lässt sich automatisch über das Setup-Skript reproduzieren.
Was bleibt erhalten:
~/.ssh/) und GPG-Keys (~/.gnupg/)~/.openclaw/)~/.config/himalaya/)Was wird neu erstellt:
Ein Word zur Sicherheit:
Die Kombination aus:
sudo bash setup_new_pi.sh bis zum ersten Testlauf des Agenten.achim@raspi:~/.openclaw/scripts $ cat backup_home.sh
#!/bin/bash
# Backup script for /home/achim
#
# Runs daily at 5:30 via cron (crontab -l)
# Creates a full directory copy via rsync to /media/achim/raspibackup/achimshome_YYYYMMDD
#
# EXCLUDED (clean rebuild):
# .cache/ – Browser-, pip-, thumbnails-Cache → wird bei Bedarf neu erzeugt
# .npm/ – npm-Package-Cache → wird per npm install neu geholt
# .local/share/Trash/ – Papierkorb
# **/node_modules/ – Kann per npm ci installiert werden
#
# Retention policy:
# - Daily backups: keep 7 days
# - Weekly backups (Sundays): keep last 5
# - Monthly backups (1st of month): keep last 12
# - Yearly backups (January 1st): keep forever
set -euo pipefail
BACKUP_SRC="/home/achim"
BACKUP_BASE="/media/achim/raspibackup"
DATE=$(date +%Y%m%d)
BACKUP_DIR="${BACKUP_BASE}/achimshome_${DATE}"
LOG_FILE="${BACKUP_BASE}/backup.log"
# ─── Exclude-Patterns ───────────────────────────────────────────────
# Caches, Papierkorb, node_modules – alles, was auf einem neuen Pi
# automatisch oder per setup_new_pi.sh neu aufgebaut wird.
EXCLUDES=(
--exclude='.cache/'
--exclude='.npm/'
--exclude='.local/share/Trash/'
--exclude='**/node_modules/'
# Falls Rust/Cargo installiert ist → Cargo-Registry raus
--exclude='.cargo/registry/'
--exclude='.cargo/git/'
# Python-Wheel-Cache
--exclude='.cache/pip/'
)
# Ensure base dir exists
mkdir -p "$BACKUP_BASE"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "$LOG_FILE"
}
log_stdout() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"
}
log_stdout "=== Backup started ==="
# --- Pre-checks ---
if [ ! -d "$BACKUP_SRC" ]; then
log_stdout "ERROR: Source $BACKUP_SRC does not exist"
exit 1
fi
if [ ! -d "$BACKUP_BASE" ]; then
log_stdout "ERROR: Destination $BACKUP_BASE not accessible"
exit 1
fi
# --- Create backup ---
log_stdout "Creating backup at $BACKUP_DIR ..."
rsync "${EXCLUDES[@]}" -rltD --no-perms --no-owner --no-group --info=name0 \
"$BACKUP_SRC/" "$BACKUP_DIR/" >> "$LOG_FILE" 2>&1 || {
log_stdout "ERROR: rsync failed (exit code $?)"
exit 1
}
# --- Create setup_new_pi.sh → in das Backup selbst ─────────────────
log_stdout "Generating setup_new_pi.sh ..."
cat > "$BACKUP_DIR/setup_new_pi.sh" << 'SETUP_EOF'
#!/bin/bash
# ===============================================================
# setup_new_pi.sh – Automatische Einrichtung eines neuen Pis
# aus dem Backup /media/.../achimshome_YYYYMMDD/
#
# Annahmen: Debian 13 (trixie), aarch64 (Raspberry Pi)
# Ziel: Nach Durchlauf ist der Pi funktionsgleich mit dem
# alten System (OpenClaw, Wiki, OCR, Whisper, E-Mail)
# ===============================================================
set -euo pipefail
# Sollte innerhalb des restoreten /home/achim laufen, z.B.:
# cd /home/achim && sudo bash /home/achim/setup_new_pi.sh
log() { echo "[$(date '+%H:%M:%S')] $*"; }
# ─── 1. System-Pakete ───────────────────────────────────────────────
log "=== Phase 1: System-Pakete ==="
apt-get update -qq
apt-get install -y -qq \
build-essential cmake git curl wget \
ffmpeg \
python3 python3-pip python3-venv \
nginx \
tesseract-ocr tesseract-ocr-deu \
exfatprogs
# Node.js 22.x von nodesource
if ! command -v node &>/dev/null; then
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
apt-get install -y -qq nodejs
fi
log "node $(node --version), npm $(npm --version)"
# ─── 2. Globale npm-Pakete ──────────────────────────────────────────
log "=== Phase 2: OpenClaw (npm global) ==="
npm install -g openclaw clawhub 2>&1 | tail -1
# ─── 3. Himalaya (E-Mail) ───────────────────────────────────────────
log "=== Phase 3: Himalaya ==="
if [ ! -f /usr/local/bin/himalaya ]; then
log "Downloading himalaya v1.2.0 (aarch64 static)..."
curl -fsSL -o /tmp/himalaya.tar.gz \
"https://github.com/soywod/himalaya/releases/download/v1.2.0/himalaya-linux-aarch64-musl.tar.gz"
cd /tmp && tar xzf himalaya.tar.gz himalaya
mv /tmp/himalaya /usr/local/bin/himalaya
chmod 755 /usr/local/bin/himalaya
fi
# ─── 4. Meilisearch ─────────────────────────────────────────────────
log "=== Phase 4: Meilisearch ==="
MEILI_DIR="$HOME/.openclaw/meilisearch"
if [ ! -f "$MEILI_DIR/meilisearch" ]; then
mkdir -p "$MEILI_DIR/data" "$MEILI_DIR/dumps"
log "Downloading meilisearch v1.43.0 (aarch64)..."
curl -fsSL -o /tmp/meilisearch.gz \
"https://github.com/meilisearch/meilisearch/releases/download/v1.43.0/meilisearch-linux-aarch64.gz"
gunzip -f /tmp/meilisearch.gz
chmod 755 /tmp/meilisearch
mv /tmp/meilisearch "$MEILI_DIR/meilisearch"
fi
# Systemd-Service
cat > /etc/systemd/system/meilisearch.service << 'MEILI_SVC'
[Unit]
Description=Meilisearch für Achims Wiki
After=network.target
[Service]
Type=simple
User=achim
WorkingDirectory=/home/achim
ExecStart=/home/achim/.openclaw/meilisearch/meilisearch --db-path /home/achim/.openclaw/meilisearch/data --env development --http-addr 127.0.0.1:7700
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
MEILI_SVC
systemctl daemon-reload
systemctl enable --now meilisearch
# ─── 5. Python-Venvs ────────────────────────────────────────────────
log "=== Phase 5: Python-Venvs ==="
# Whisper (base model → schnell/genügend für Pi)
if [ ! -d "$HOME/whisper_light" ]; then
python3 -m venv "$HOME/whisper_light"
"$HOME/whisper_light/bin/pip" install faster-whisper
mkdir -p "$HOME/.openclaw/speech_models"
fi
# OCR-Venv
if [ ! -d "$HOME/imgocr" ]; then
python3 -m venv "$HOME/imgocr"
"$HOME/imgocr/bin/pip" install opencv-python-headless numpy
fi
# ─── 6. Wiki-Dateien (nginx) ────────────────────────────────────────
log "=== Phase 6: Wiki (nginx) ==="
if [ -f "$HOME/.openclaw/workspace/AchimsDaten/wiki_contents/index.html" ]; then
rm -f /var/www/html/wiki 2>/dev/null
ln -sf "$HOME/.openclaw/workspace/AchimsDaten/wiki_contents" /var/www/html/wiki
systemctl restart nginx || true
fi
# ─── 7. Cron-Job für Backup ─────────────────────────────────────────
log "=== Phase 7: Cron-Job ==="
if ! crontab -l 2>/dev/null | grep -q backup_home; then
(crontab -l 2>/dev/null; echo "30 5 * * * /home/achim/.openclaw/scripts/backup_home.sh") | crontab -
fi
# ─── 8. Meilisearch-Import ──────────────────────────────────────────
log "=== Phase 8: Wiki-Index erneuern ==="
if [ -f "$HOME/.openclaw/agents/helbardor/index_all_files.py" ]; then
cd "$HOME/.openclaw/agents/helbardor"
python3 index_all_files.py 2>/dev/null || log "WARNING: Index-Script fehlgeschlagen (Meilisearch noch nicht bereit?)"
fi
# ─── Fertig! ─────────────────────────────────────────────────────────
log ""
log "========================================================"
log " Setup abgeschlossen!"
log " Nächste Schritte:"
log " 1. Prüfe dass openclaw läuft: openclaw gateway status"
log " 2. SSH-Keys testen"
log " 3. Wiki aufrufen: http://$(hostname -I | awk '{print $1}')/"
log "========================================================"
SETUP_EOF
chmod +x "$BACKUP_DIR/setup_new_pi.sh"
# Touch directory to set a clean timestamp
touch "$BACKUP_DIR"
log_stdout "Backup completed: $BACKUP_DIR"
# ─── Retention cleanup ──────────────────────────────────────────────
log_stdout "=== Retention cleanup started ==="
shopt -s nullglob
backups=("$BACKUP_BASE"/achimshome_*)
shopt -u nullglob
if [ ${#backups[@]} -eq 0 ]; then
log_stdout "No existing backups found for retention check"
log_stdout "=== Backup finished ==="
exit 0
fi
# Sort by directory name (achimshome_YYYYMMDD → oldest first)
IFS=$'\n' sorted_backups=($(sort <<<"${backups[*]}")); unset IFS
today_epoch=$(date +%s)
seven_days_ago=$((today_epoch - 7*24*60*60))
declare -a monthly_dirs=()
declare -a weekly_dirs=()
for dir in "${sorted_backups[@]}"; do
dirname=$(basename "$dir")
datestr="${dirname#achimshome_}"
if ! [[ "$datestr" =~ ^[0-9]{8}$ ]]; then
log_stdout "WARNING: Skipping non-standard directory: $dirname"
continue
fi
dir_epoch=$(date -d "${datestr:0:4}-${datestr:4:2}-${datestr:6:2}" +%s 2>/dev/null || true)
if [ -z "$dir_epoch" ]; then
log_stdout "WARNING: Cannot parse date for $dirname, skipping"
continue
fi
day_of_week=$(date -d "@$dir_epoch" +%u) # 1=Mon .. 7=Sun
day_of_month="${datestr:6:2}"
month="${datestr:4:2}"
# Skip today's backup (just created) — never delete it
if [ "$dir" = "$BACKUP_DIR" ]; then
log_stdout "Retaining (today): $dirname"
continue
fi
if [ "$day_of_month" = "01" ] && [ "$month" = "01" ]; then
# Yearly backup (Jan 1) – keep forever
log_stdout "Retaining (yearly): $dirname"
elif [ "$day_of_month" = "01" ]; then
# Monthly backup (1st of month)
monthly_dirs+=("$dir")
elif [ "$day_of_week" = "7" ]; then
# Weekly backup (Sunday)
weekly_dirs+=("$dir")
elif [ "$dir_epoch" -ge "$seven_days_ago" ]; then
# Daily backup, younger than 7 days
log_stdout "Retaining (daily): $dirname"
else
# Old daily backup – delete
log_stdout "Deleting old daily backup: $dirname"
rm -rf "$dir"
fi
done
# Keep only the 12 most recent monthly backups
if [ ${#monthly_dirs[@]} -gt 12 ]; then
delete_count=$(( ${#monthly_dirs[@]} - 12 ))
for ((i=0; i<delete_count; i++)); do
log_stdout "Deleting old monthly backup: $(basename "${monthly_dirs[$i]}")"
rm -rf "${monthly_dirs[$i]}"
done
fi
for dir in "${monthly_dirs[@]}"; do
if [ -d "$dir" ]; then
log_stdout "Retaining (monthly): $(basename "$dir")"
fi
done
# Keep only the 5 most recent weekly backups
if [ ${#weekly_dirs[@]} -gt 5 ]; then
delete_count=$(( ${#weekly_dirs[@]} - 5 ))
for ((i=0; i<delete_count; i++)); do
log_stdout "Deleting old weekly backup: $(basename "${weekly_dirs[$i]}")"
rm -rf "${weekly_dirs[$i]}"
done
fi
for dir in "${weekly_dirs[@]}"; do
if [ -d "$dir" ]; then
log_stdout "Retaining (weekly): $(basename "$dir")"
fi
done
log_stdout "=== Backup finished ===
achim@raspi:~/.openclaw/scripts $ cat setup_new_pi.sh
#!/bin/bash
# ===============================================================
# setup_new_pi.sh – Automatische Einrichtung eines neuen Pis
# aus dem Backup /media/.../achimshome_YYYYMMDD/
#
# Annahmen: Debian 13 (trixie), aarch64 (Raspberry Pi)
# Ziel: Nach Durchlauf ist der Pi funktionsgleich mit dem
# alten System (OpenClaw, Wiki, OCR, Whisper, E-Mail)
#
# Nutzung: Nachdem das Backup auf den neuen Pi kopiert wurde:
# cd /home/achim && sudo bash setup_new_pi.sh
# ===============================================================
set -euo pipefail
log() { echo "[$(date '+%H:%M:%S')] $*"; }
# ─── 0. Prüfung ─────────────────────────────────────────────────────
if [ "$(id -u)" -ne 0 ]; then
echo "❌ Dieses Skript muss als root laufen! (sudo bash $0)"
exit 1
fi
log "=== Setup für neuen Raspberry Pi gestartet ==="
# ─── 1. System-Pakete ───────────────────────────────────────────────
log "=== Phase 1: System-Pakete ==="
apt-get update -qq
apt-get install -y -qq \
build-essential cmake git curl wget \
ffmpeg \
python3 python3-pip python3-venv \
nginx \
tesseract-ocr tesseract-ocr-deu \
exfatprogs
# Node.js 22.x von nodesource
if ! command -v node &>/dev/null; then
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
apt-get install -y -qq nodejs
fi
log "✓ node $(node --version), npm $(npm --version)"
# ─── 2. Globale npm-Pakete ──────────────────────────────────────────
log "=== Phase 2: OpenClaw (npm global) ==="
npm install -g openclaw clawhub 2>&1 | tail -1
log "✓ OpenClaw installiert"
# ─── 3. Himalaya (E-Mail) ───────────────────────────────────────────
log "=== Phase 3: Himalaya (E-Mail) ==="
if [ ! -f /usr/local/bin/himalaya ]; then
log "→ Download himalaya v1.2.0 (aarch64 static)..."
curl -fsSL -o /tmp/himalaya.tar.gz \
"https://github.com/soywod/himalaya/releases/download/v1.2.0/himalaya-linux-aarch64-musl.tar.gz"
cd /tmp && tar xzf himalaya.tar.gz himalaya
mv /tmp/himalaya /usr/local/bin/himalaya
chmod 755 /usr/local/bin/himalaya
fi
log "✓ Himalaya installiert"
# ─── 4. Meilisearch ─────────────────────────────────────────────────
log "=== Phase 4: Meilisearch ==="
MEILI_DIR="$HOME/.openclaw/meilisearch"
if [ ! -f "$MEILI_DIR/meilisearch" ]; then
mkdir -p "$MEILI_DIR/data" "$MEILI_DIR/dumps"
log "→ Download meilisearch v1.43.0 (aarch64)..."
curl -fsSL -o /tmp/meilisearch.gz \
"https://github.com/meilisearch/meilisearch/releases/download/v1.43.0/meilisearch-linux-aarch64.gz"
gunzip -f /tmp/meilisearch.gz
chmod 755 /tmp/meilisearch
mv /tmp/meilisearch "$MEILI_DIR/meilisearch"
fi
cat > /etc/systemd/system/meilisearch.service << 'MEILI_SVC'
[Unit]
Description=Meilisearch für Achims Wiki
After=network.target
[Service]
Type=simple
User=achim
WorkingDirectory=/home/achim
ExecStart=/home/achim/.openclaw/meilisearch/meilisearch --db-path /home/achim/.openclaw/meilisearch/data --env development --http-addr 127.0.0.1:7700
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
MEILI_SVC
systemctl daemon-reload
systemctl enable --now meilisearch
log "✓ Meilisearch läuft"
# ─── 5. Python-Venvs ────────────────────────────────────────────────
log "=== Phase 5: Python-Venvs ==="
# Whisper
if [ ! -d "$HOME/whisper_light" ]; then
python3 -m venv "$HOME/whisper_light"
"$HOME/whisper_light/bin/pip" install faster-whisper
mkdir -p "$HOME/.openclaw/speech_models"
log "✓ Whisper (base) installiert"
fi
# OCR
if [ ! -d "$HOME/imgocr" ]; then
python3 -m venv "$HOME/imgocr"
"$HOME/imgocr/bin/pip" install opencv-python-headless numpy
log "✓ OCR-Venv installiert"
fi
# beem (Hive-Zugriff)
pip3 install beem 2>/dev/null || true
log "✓ Python-Tools (beem) installiert"
# ─── 6. Wiki (nginx) ────────────────────────────────────────────────
log "=== Phase 6: Wiki (nginx) ==="
if [ -f "$HOME/.openclaw/workspace/AchimsDaten/wiki_contents/index.html" ]; then
rm -f /var/www/html/wiki 2>/dev/null
ln -sf "$HOME/.openclaw/workspace/AchimsDaten/wiki_contents" /var/www/html/wiki
fi
systemctl restart nginx || true
log "✓ Nginx konfiguriert"
# ─── 7. Cron-Job für Backup ─────────────────────────────────────────
log "=== Phase 7: Cron-Job ==="
if ! crontab -u achim -l 2>/dev/null | grep -q backup_home; then
(crontab -u achim -l 2>/dev/null; echo "30 5 * * * /home/achim/.openclaw/scripts/backup_home.sh") | crontab -u achim -
log "✓ Cron-Job eingerichtet"
fi
# ─── 8. Wiki-Index ---────────────────────────────────────────────────
log "=== Phase 8: Meilisearch-Index ==="
if [ -f "$HOME/.openclaw/agents/helbardor/index_all_files.py" ]; then
cd "$HOME/.openclaw/agents/helbardor"
su -c "cd $HOME/.openclaw/agents/helbardor && python3 index_all_files.py 2>/dev/null" achim || log "⚠ Index aufbauen später per Hand: cd ~/.openclaw/agents/helbardor && python3 index_all_files.py"
fi
# ─── 9. Berechtigungen ──────────────────────────────────────────────
chown -R achim:achim "$HOME" 2>/dev/null || true
# ─── Fertig! ─────────────────────────────────────────────────────────
echo ""
echo "========================================================"
echo " ✅ Setup abgeschlossen!"
echo ""
echo " Nächste Schritte:"
echo " 1. Als achim neu einloggen: su - achim"
echo " 2. OpenClaw testen: openclaw gateway status"
echo " 3. SSH-Keys prüfen"
echo " 4. Wiki besuchen: http://$(hostname -I | awk '{print $1}')/"
echo "========================================================"
Geschrieben am 2026-06-09 für mein persönliches Wiki von mir Achim Mertens mit Hilfe von Openclaw