#!/bin/bash # ==================== Telegram Bot Systemd 服务安装脚本 ==================== # 用法: sudo bash install_service.sh [install|uninstall|status|logs] set -e # ==================== 配置 ==================== SERVICE_NAME="oai-team-bot" SERVICE_DESC="OpenAI Team Provisioner Bot" WORK_DIR="$(cd "$(dirname "$0")" && pwd)" SCRIPT_NAME="telegram_bot.py" USER="${SUDO_USER:-root}" # 颜色输出 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_success() { echo -e "${GREEN}[OK]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } # ==================== 检查环境 ==================== check_env() { # 检查是否为 root if [ "$EUID" -ne 0 ]; then log_error "请使用 sudo 运行此脚本" exit 1 fi # 检查工作目录 if [ ! -f "${WORK_DIR}/${SCRIPT_NAME}" ]; then log_error "找不到 ${SCRIPT_NAME},请在项目目录下运行此脚本" exit 1 fi # 检测 uv if command -v uv &> /dev/null && [ -f "${WORK_DIR}/pyproject.toml" ]; then UV_BIN=$(which uv) # 先执行 uv sync 安装依赖 log_info "执行 uv sync 安装依赖..." cd "${WORK_DIR}" sudo -u ${USER} ${UV_BIN} sync log_success "依赖安装完成" # 使用 uv run 运行 EXEC_CMD="${UV_BIN} run python ${SCRIPT_NAME}" log_info "使用 uv run 运行" elif [ -f "${WORK_DIR}/.venv/bin/python" ]; then # 使用 .venv EXEC_CMD="${WORK_DIR}/.venv/bin/python ${WORK_DIR}/${SCRIPT_NAME}" log_info "使用 .venv 虚拟环境" else # 使用系统 python PYTHON_BIN=$(which python3 || which python) if [ -z "$PYTHON_BIN" ]; then log_error "找不到 Python 或 uv" exit 1 fi EXEC_CMD="${PYTHON_BIN} ${WORK_DIR}/${SCRIPT_NAME}" log_warn "使用系统 Python,可能缺少依赖" fi log_info "工作目录: ${WORK_DIR}" log_info "启动命令: ${EXEC_CMD}" log_info "运行用户: ${USER}" } # ==================== 安装服务 ==================== install_service() { log_info "正在安装 ${SERVICE_NAME} 服务..." # 获取 uv 路径用于 PATH UV_PATH="" if command -v uv &> /dev/null; then UV_PATH="$(dirname $(which uv)):" fi # 创建 systemd service 文件 cat > /etc/systemd/system/${SERVICE_NAME}.service << EOF [Unit] Description=${SERVICE_DESC} After=network.target network-online.target Wants=network-online.target [Service] Type=simple User=${USER} Group=${USER} WorkingDirectory=${WORK_DIR} ExecStart=${EXEC_CMD} Restart=always RestartSec=10 StandardOutput=journal StandardError=journal # 环境变量 Environment="PYTHONUNBUFFERED=1" Environment="LOG_LEVEL=INFO" Environment="PATH=${UV_PATH}/usr/local/bin:/usr/bin:/bin" Environment="HOME=/root" # 安全限制 (root 用户不使用 ProtectSystem) NoNewPrivileges=true [Install] WantedBy=multi-user.target EOF log_success "服务文件已创建: /etc/systemd/system/${SERVICE_NAME}.service" # 重新加载 systemd systemctl daemon-reload log_success "systemd 配置已重载" # 启用开机自启 systemctl enable ${SERVICE_NAME} log_success "已启用开机自启" # 启动服务 systemctl start ${SERVICE_NAME} log_success "服务已启动" # 显示状态 echo "" systemctl status ${SERVICE_NAME} --no-pager echo "" log_success "安装完成!" echo "" echo "常用命令:" echo " 查看状态: sudo systemctl status ${SERVICE_NAME}" echo " 查看日志: sudo journalctl -u ${SERVICE_NAME} -f" echo " 重启服务: sudo systemctl restart ${SERVICE_NAME}" echo " 停止服务: sudo systemctl stop ${SERVICE_NAME}" echo " 卸载服务: sudo bash $0 uninstall" } # ==================== 卸载服务 ==================== uninstall_service() { log_info "正在卸载 ${SERVICE_NAME} 服务..." # 停止服务 systemctl stop ${SERVICE_NAME} 2>/dev/null || true log_info "服务已停止" # 禁用开机自启 systemctl disable ${SERVICE_NAME} 2>/dev/null || true log_info "已禁用开机自启" # 删除服务文件 rm -f /etc/systemd/system/${SERVICE_NAME}.service log_info "服务文件已删除" # 重新加载 systemd systemctl daemon-reload log_success "卸载完成!" } # ==================== 查看状态 ==================== show_status() { systemctl status ${SERVICE_NAME} --no-pager } # ==================== 查看日志 ==================== show_logs() { journalctl -u ${SERVICE_NAME} -f --no-pager -n 50 } # ==================== 主函数 ==================== main() { case "${1:-install}" in install) check_env install_service ;; uninstall|remove) uninstall_service ;; status) show_status ;; logs|log) show_logs ;; restart) systemctl restart ${SERVICE_NAME} log_success "服务已重启" show_status ;; stop) systemctl stop ${SERVICE_NAME} log_success "服务已停止" ;; start) systemctl start ${SERVICE_NAME} log_success "服务已启动" show_status ;; *) echo "用法: sudo bash $0 [命令]" echo "" echo "命令:" echo " install 安装并启动服务 (默认)" echo " uninstall 卸载服务" echo " status 查看服务状态" echo " logs 查看实时日志" echo " restart 重启服务" echo " start 启动服务" echo " stop 停止服务" ;; esac } main "$@"