#!/usr/bin/env bash # # Lokale Vorschau der Artikel. # # ./preview.sh -> einfacher Markdown-Server (Python, keine Abhaengigkeiten) # ./preview.sh jekyll -> Jekyll, falls GitHub Pages genutzt wird # PORT=4100 ./preview.sh -> Startport vorgeben # # Der Port wird vor dem Start geprueft. Ist er belegt, wird der naechste freie genommen, # statt den laufenden Dienst abzuschiessen oder mit "address already in use" zu sterben. # set -euo pipefail MODE="${1:-simple}" PORT="${PORT:-4000}" MAX_TRIES="${MAX_TRIES:-20}" port_is_free() { local p="$1" if command -v lsof >/dev/null 2>&1; then ! lsof -nP -iTCP:"$p" -sTCP:LISTEN >/dev/null 2>&1 elif command -v ss >/dev/null 2>&1; then ! ss -ltnH "sport = :$p" 2>/dev/null | grep -q . elif command -v netstat >/dev/null 2>&1; then ! netstat -an 2>/dev/null | grep -qE "[.:]${p}[[:space:]].*LISTEN" else # Letzter Ausweg: Verbindungsversuch. Klappt er, hoert dort jemand zu. ! (exec 3<>"/dev/tcp/127.0.0.1/$p") 2>/dev/null fi } find_free_port() { local p="$1" tries=0 while ! port_is_free "$p"; do printf 'Port %s ist belegt.\n' "$p" >&2 p=$((p + 1)) tries=$((tries + 1)) if [ "$tries" -ge "$MAX_TRIES" ]; then printf 'Kein freier Port zwischen %s und %s gefunden.\n' "$PORT" "$p" >&2 exit 1 fi done printf '%s' "$p" } PORT="$(find_free_port "$PORT")" case "$MODE" in jekyll) command -v bundle >/dev/null 2>&1 || { echo "bundler fehlt. Entweder installieren oder ./preview.sh ohne Argument nutzen." >&2 exit 1 } echo "Jekyll auf http://127.0.0.1:${PORT}" exec bundle exec jekyll serve --port "$PORT" --livereload ;; simple) command -v python3 >/dev/null 2>&1 || { echo "python3 fehlt." >&2; exit 1; } echo "Dateiserver auf http://127.0.0.1:${PORT}/artikel/" echo "(rendert kein Markdown, zeigt aber Struktur und Rohtext)" exec python3 -m http.server "$PORT" --bind 127.0.0.1 ;; *) echo "Unbekannter Modus: $MODE (erlaubt: simple, jekyll)" >&2 exit 1 ;; esac