#!/usr/bin/env bash # # setup.sh ─ 通用 systemd 注册脚本 # # 需要 root;除 -h 以外所有参数均「显式传入」,脚本本身不带任何默认业务值。 # # 用法示例: # sudo bash setup.sh \ # --name mysvc \ # --bin /opt/mysvc/mysvc \ # --args "-c /opt/mysvc/mysvc.yaml --log-level info" \ # --user nobody # # -------------------------------------------------------------- set -euo pipefail ############################ 参数解析 ############################ usage() { cat <<'EOF' 用法: sudo bash setup.sh [选项] 必要参数: -n, --name systemd 服务名 -b, --bin 可执行文件绝对路径 可选参数: --args "" 启动参数 (自动追加到 ExecStart) -e, --exec "" 完全自定义 ExecStart, 一旦使用 --args 将被忽略 --user 运行用户 (默认: nobody) --type Service Type (默认: simple) --workdir WorkingDirectory -h, --help 显示本帮助 示例: sudo bash setup.sh -n api-gw -b /srv/api-gw/bin/gw \\ --args "-conf /srv/api-gw/conf.toml" EOF exit 1 } # 初始为空,强制调用者填写 SERVICE_NAME="" BIN_PATH="" ARGS="" USER="nobody" TYPE="simple" WORKDIR="" EXEC_OVERRIDE="" while [[ $# -gt 0 ]]; do case "$1" in -n|--name) SERVICE_NAME="$2"; shift 2;; -b|--bin) BIN_PATH="$2"; shift 2;; --args) ARGS="$2"; shift 2;; -e|--exec) EXEC_OVERRIDE="$2";shift 2;; --user) USER="$2"; shift 2;; --type) TYPE="$2"; shift 2;; --workdir) WORKDIR="$2"; shift 2;; -h|--help) usage;; *) echo "未知参数: $1" >&2; usage;; esac done # 必要参数校验 [[ -z $SERVICE_NAME || -z $BIN_PATH ]] && { echo "❌ 必须指定 --name 与 --bin" >&2; usage; } [[ $EUID -ne 0 ]] && { echo "❌ 需要 root 权限运行" >&2; exit 1; } [[ ! -x $BIN_PATH ]] && { echo "❌ 可执行文件不存在或不可执行: $BIN_PATH" >&2; exit 1; } ########################## systemd unit ######################### SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service" if [[ -n $EXEC_OVERRIDE ]]; then EXEC_START="$EXEC_OVERRIDE" else EXEC_START="$BIN_PATH" [[ -n $ARGS ]] && EXEC_START+=" $ARGS" fi cat >"$SERVICE_FILE" <