logbuch/preview.sh

67 lines
2 KiB
Bash
Executable file

#!/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