#!/usr/bin/env bash set -euo pipefail WATCH_DIR="/private/argus/etc" ZONE_DB="/private/argus/bind/db.argus.com" LOCKFILE="/var/lock/argus_dns_sync.lock" BACKUP_DIR="/private/argus/bind/.backup" SLEEP_SECONDS=10 RELOAD_SCRIPT="/usr/local/bin/reload-bind9.sh" # 这里放你已有脚本的路径 mkdir -p "$(dirname "$LOCKFILE")" "$BACKUP_DIR" BACKUP_UID="${ARGUS_BUILD_UID:-2133}" BACKUP_GID="${ARGUS_BUILD_GID:-2015}" chown -R "$BACKUP_UID:$BACKUP_GID" "$BACKUP_DIR" 2>/dev/null || true is_ipv4() { local ip="$1" [[ "$ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]] || return 1 IFS='.' read -r a b c d <<<"$ip" for n in "$a" "$b" "$c" "$d"; do (( n >= 0 && n <= 255 )) || return 1 done return 0 } get_current_ip() { local name="$1" sed -n -E "s/^${name}[[:space:]]+IN[[:space:]]+A[[:space:]]+([0-9.]+)[[:space:]]*$/\1/p" "$ZONE_DB" | head -n1 } upsert_record() { local name="$1" local new_ip="$2" local ts ts="$(date +%Y%m%d-%H%M%S)" local changed=0 cp -a "$ZONE_DB" "$BACKUP_DIR/db.argus.com.$ts.bak" chown "$BACKUP_UID:$BACKUP_GID" "$BACKUP_DIR/db.argus.com.$ts.bak" 2>/dev/null || true local cur_ip cur_ip="$(get_current_ip "$name" || true)" if [[ -z "$cur_ip" ]]; then # Ensure the file ends with a newline before adding new record if [[ -s "$ZONE_DB" ]] && [[ $(tail -c1 "$ZONE_DB" | wc -l) -eq 0 ]]; then echo "" >> "$ZONE_DB" fi printf "%-20s IN A %s\n" "$name" "$new_ip" >> "$ZONE_DB" echo "[ADD] ${name} -> ${new_ip}" changed=1 elif [[ "$cur_ip" != "$new_ip" ]]; then awk -v n="$name" -v ip="$new_ip" ' { if ($1==n && $2=="IN" && $3=="A") { printf "%-20s IN A %s\n", n, ip } else { print } } ' "$ZONE_DB" > "${ZONE_DB}.tmp" && mv "${ZONE_DB}.tmp" "$ZONE_DB" echo "[UPDATE] ${name}: ${cur_ip} -> ${new_ip}" changed=1 else echo "[SKIP] ${name} unchanged (${new_ip})" fi if [[ $changed -eq 1 ]]; then return 0 fi return 1 } while true; do exec 9>"$LOCKFILE" if flock -n 9; then shopt -s nullglob NEED_RELOAD=0 for f in "$WATCH_DIR"/*.argus.com; do base="$(basename "$f")" name="${base%.argus.com}" ip="$(grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' "$f" | tail -n1 || true)" if [[ -z "$ip" ]] || ! is_ipv4 "$ip"; then echo "[WARN] $f 未找到有效 IPv4,跳过" continue fi if upsert_record "$name" "$ip"; then NEED_RELOAD=1 fi done if [[ $NEED_RELOAD -eq 1 ]]; then echo "[INFO] 检测到 db.argus.com 变更,执行 reload-bind9.sh" bash "$RELOAD_SCRIPT" fi flock -u 9 else echo "[INFO] 已有同步任务在运行,跳过本轮" fi sleep "$SLEEP_SECONDS" done