#!/usr/bin/env bash # Установка DMR-сервера. Debian/Ubuntu, systemd. Зависимостей нет — только python3. # # sudo bash install.sh # # Повторный запуск безопасен: конфиг и пароли не перезаписываются. set -euo pipefail APP=dmr-server DEST=/opt/$APP CFGDIR=/etc/$APP USER=dmrsrv SRC="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" [ "$(id -u)" = 0 ] || { echo "нужен root: sudo bash install.sh" >&2; exit 1; } command -v python3 >/dev/null || { echo "==> ставлю python3" DEBIAN_FRONTEND=noninteractive apt-get update -qq DEBIAN_FRONTEND=noninteractive apt-get install -y -qq python3 } PYV=$(python3 -c 'import sys;print("%d.%d"%sys.version_info[:2])') python3 - <<'PY' || { echo "нужен Python 3.10+, найден $PYV" >&2; exit 1; } import sys; sys.exit(0 if sys.version_info >= (3, 10) else 1) PY echo "==> python3 $PYV" echo "==> служебный пользователь $USER" id "$USER" >/dev/null 2>&1 || useradd --system --no-create-home --shell /usr/sbin/nologin "$USER" echo "==> код в $DEST" install -d -m 755 "$DEST" rm -rf "$DEST/dmrsrv" cp -r "$SRC/dmrsrv" "$DEST/dmrsrv" [ -d "$SRC/tests" ] && { rm -rf "$DEST/tests"; cp -r "$SRC/tests" "$DEST/tests"; } find "$DEST" -name '__pycache__' -type d -exec rm -rf {} + 2>/dev/null || true chown -R root:root "$DEST" echo "==> конфигурация в $CFGDIR" install -d -m 750 -o "$USER" -g "$USER" "$CFGDIR" if [ -f "$CFGDIR/config.json" ]; then echo " config.json уже есть — не трогаю" else # Пароль панели сервер сгенерирует сам при первом запуске и напишет в журнал. cat > "$CFGDIR/config.json" <<'JSON' { "bind": "0.0.0.0", "port": 62031, "passphrase": "passw0rd", "panel": { "bind": "0.0.0.0", "port": 8080, "user": "admin", "password": "" }, "groups": [ { "tg": 9, "name": "Локальная", "slot": 2 }, { "tg": 1, "name": "Общая", "slot": 1 } ], "parrot": { "enabled": true, "tg": 9990, "delay": 2.0 }, "peers_allowlist": [], "log_keep": 500 } JSON chown "$USER:$USER" "$CFGDIR/config.json" chmod 600 "$CFGDIR/config.json" echo " создан конфиг по умолчанию (ОБЯЗАТЕЛЬНО смени passphrase в панели)" fi echo "==> systemd" cat > /etc/systemd/system/$APP.service < служба работает" else echo "==> СЛУЖБА НЕ ПОДНЯЛАСЬ:"; journalctl -u $APP -n 20 --no-pager; exit 1 fi PORT=$(python3 -c "import json;print(json.load(open('$CFGDIR/config.json'))['port'])") PPORT=$(python3 -c "import json;print(json.load(open('$CFGDIR/config.json'))['panel']['port'])") PPASS=$(python3 -c "import json;print(json.load(open('$CFGDIR/config.json'))['panel']['password'])" 2>/dev/null || true) IP=$(hostname -I 2>/dev/null | awk '{print $1}') cat <} └──────────────────────────────────────────────────────────── Журнал: journalctl -u $APP -f Перезапуск: systemctl restart $APP В Pi-Star: Configuration -> DMR Master -> DMRGateway/"DMR Master" указать этот адрес и порт $PORT, пароль — passphrase из конфига. INFO