Cron-sicheres Locking (Lockdir+PID), Running-Mark, Cleanup via trap
This commit is contained in:
parent
de728f7c8f
commit
95ac12bbe2
@ -1,15 +1,18 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Beschreibung: Minecraft → ntfy Notifier (Join/Leave + optional Up/Down)
|
# Beschreibung: Minecraft → ntfy Notifier (Join/Leave + optional Up/Down) mit Cron-safe Locking
|
||||||
# Autor: Patrick Asmus
|
# Autor: Patrick Asmus
|
||||||
# Web: https://www.cleveradmin.de
|
# Web: https://www.cleveradmin.de
|
||||||
# Repository: https://git.techniverse.net/scriptos/minecraft-ntfy-notify
|
# Repository: https://git.techniverse.net/scriptos/minecraft-ntfy-notify
|
||||||
# Version: 1.2
|
# Version: 1.3
|
||||||
# Datum: 18.09.2025
|
# Datum: 18.09.2025
|
||||||
# Modifikation: Spielername in Meldungen in Anführungszeichen gesetzt; Sanitizing beibehalten
|
# Modifikation: Cron-sicheres Locking (Lockdir+PID), Running-Mark, Cleanup via trap
|
||||||
#####################################################
|
#####################################################
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Robustes PATH für Cron
|
||||||
|
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
if [[ -f "${SCRIPT_DIR}/.env" ]]; then
|
if [[ -f "${SCRIPT_DIR}/.env" ]]; then
|
||||||
set -a
|
set -a
|
||||||
@ -42,6 +45,14 @@ STATE_DIR="${STATE_DIR:-${SCRIPT_DIR}/state}"
|
|||||||
STATE_PLAYERS="${STATE_DIR}/players.prev"
|
STATE_PLAYERS="${STATE_DIR}/players.prev"
|
||||||
STATE_UP="${STATE_DIR}/server_up.prev"
|
STATE_UP="${STATE_DIR}/server_up.prev"
|
||||||
|
|
||||||
|
# Lock & Running-Mark (pro MC_HOST:RCON_PORT:NTFY_TOPIC eindeutig)
|
||||||
|
# -> erlaubt mehrere parallele Instanzen für verschiedene Server/Topics
|
||||||
|
LOCK_KEY="$(printf '%s' "${MC_HOST}_${RCON_PORT}_${NTFY_TOPIC}" | tr -c 'A-Za-z0-9._-' '_')"
|
||||||
|
RUN_DIR="${RUN_DIR:-${STATE_DIR}}"
|
||||||
|
LOCK_DIR="${RUN_DIR}/lock.${LOCK_KEY}"
|
||||||
|
PID_FILE="${LOCK_DIR}/pid"
|
||||||
|
RUN_MARK="${RUN_DIR}/running.${LOCK_KEY}"
|
||||||
|
|
||||||
# Optional Debug
|
# Optional Debug
|
||||||
DEBUG="${DEBUG:-false}"
|
DEBUG="${DEBUG:-false}"
|
||||||
|
|
||||||
@ -50,6 +61,44 @@ die() { echo "ERROR: $*" >&2; exit 1; }
|
|||||||
need_bin() { command -v "$1" >/dev/null 2>&1 || die "Benötigtes Tool fehlt: $1"; }
|
need_bin() { command -v "$1" >/dev/null 2>&1 || die "Benötigtes Tool fehlt: $1"; }
|
||||||
dbg() { [[ "$DEBUG" == "true" ]] && echo "DBG: $*" >&2 || true; }
|
dbg() { [[ "$DEBUG" == "true" ]] && echo "DBG: $*" >&2 || true; }
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
# Lauf-Mark und Lock sauber entfernen
|
||||||
|
rm -f "$RUN_MARK" 2>/dev/null || true
|
||||||
|
rm -f "$PID_FILE" 2>/dev/null || true
|
||||||
|
rmdir "$LOCK_DIR" 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
acquire_lock() {
|
||||||
|
mkdir -p "$RUN_DIR"
|
||||||
|
# Atomarer Lock-Versuch
|
||||||
|
if mkdir "$LOCK_DIR" 2>/dev/null; then
|
||||||
|
echo "$$" > "$PID_FILE"
|
||||||
|
trap cleanup EXIT INT TERM
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Lock existiert -> prüfen, ob Prozess noch lebt
|
||||||
|
if [[ -f "$PID_FILE" ]]; then
|
||||||
|
oldpid="$(cat "$PID_FILE" 2>/dev/null || true)"
|
||||||
|
if [[ -n "${oldpid:-}" ]] && kill -0 "$oldpid" 2>/dev/null; then
|
||||||
|
# Schon aktiv → leise beenden (Cron-safe)
|
||||||
|
dbg "Bereits laufend (PID $oldpid), beende."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Stale Lock entfernen und erneut versuchen
|
||||||
|
rm -rf "$LOCK_DIR" 2>/dev/null || true
|
||||||
|
if mkdir "$LOCK_DIR" 2>/dev/null; then
|
||||||
|
echo "$$" > "$PID_FILE"
|
||||||
|
trap cleanup EXIT INT TERM
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Falls wir hier landen, ist wirklich etwas schief
|
||||||
|
die "Konnte Lock nicht übernehmen: ${LOCK_DIR}"
|
||||||
|
}
|
||||||
|
|
||||||
ntfy_notify() {
|
ntfy_notify() {
|
||||||
local title="$1" body="$2" tags="$3" priority="$4"
|
local title="$1" body="$2" tags="$3" priority="$4"
|
||||||
[[ -z "$NTFY_SERVER" || -z "$NTFY_TOPIC" ]] && { echo "ntfy Server/Topic fehlt – skip"; return 1; }
|
[[ -z "$NTFY_SERVER" || -z "$NTFY_TOPIC" ]] && { echo "ntfy Server/Topic fehlt – skip"; return 1; }
|
||||||
@ -81,11 +130,8 @@ get_players() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
dbg "RAW: $out"
|
dbg "RAW: $out"
|
||||||
|
|
||||||
out="$(printf '%s' "$out" | sanitize)"
|
out="$(printf '%s' "$out" | sanitize)"
|
||||||
|
|
||||||
# "There are 0 of a max of 20 players online"
|
|
||||||
# "There are 2 of a max of 20 players online: Alice, Bob"
|
|
||||||
if ! grep -q "players online:" <<<"$out"; then
|
if ! grep -q "players online:" <<<"$out"; then
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
@ -105,16 +151,22 @@ get_players() {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
# ===== Checks =====
|
# ===== Checks & Lock =====
|
||||||
need_bin curl
|
need_bin curl
|
||||||
need_bin mcrcon
|
need_bin mcrcon
|
||||||
[[ -n "${NTFY_SERVER}" && -n "${NTFY_TOPIC}" ]] || die "NTFY_SERVER/NTFY_TOPIC nicht gesetzt"
|
[[ -n "${NTFY_SERVER}" && -n "${NTFY_TOPIC}" ]] || die "NTFY_SERVER/NTFY_TOPIC nicht gesetzt"
|
||||||
ensure_state
|
ensure_state
|
||||||
|
acquire_lock
|
||||||
|
|
||||||
echo "Starte Polling ${MC_HOST}:${RCON_PORT} → ntfy ${NTFY_SERVER}/${NTFY_TOPIC}"
|
echo "Starte Polling ${MC_HOST}:${RCON_PORT} → ntfy ${NTFY_SERVER}/${NTFY_TOPIC} (PID $$)"
|
||||||
prev_up="$(cat "$STATE_UP")"
|
prev_up="$(cat "$STATE_UP")"
|
||||||
|
|
||||||
|
# ===== Main Loop =====
|
||||||
while :; do
|
while :; do
|
||||||
|
# Running-Mark aktualisieren (für Monitoring/„läuft“-Check)
|
||||||
|
date -Iseconds > "$RUN_MARK"
|
||||||
|
echo "$$" >> "$RUN_MARK"
|
||||||
|
|
||||||
tmp_players="$(mktemp)"
|
tmp_players="$(mktemp)"
|
||||||
if get_players >"$tmp_players"; then
|
if get_players >"$tmp_players"; then
|
||||||
server_up="true"
|
server_up="true"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user