#!/bin/bash # ======================================== # 拾音器异响检测系统启动脚本 # ======================================== # # 使用方法: # ./start.sh # 前台运行 # ./start.sh -d # 后台运行 # ./start.sh --daemon # 后台运行 # ./start.sh stop # 停止服务 # ./start.sh restart # 重启服务 # ./start.sh status # 查看状态 # # 日志文件: # 前台运行:直接输出到控制台 # 后台运行:logs/system.log(RotatingFileHandler 自动轮转) # # 切换到脚本所在目录 cd "$(dirname "$0")" # PID文件路径 PID_FILE="logs/pid.txt" # ======================================== # 函数:激活conda环境 # ======================================== activate_conda() { if command -v conda &> /dev/null; then # 激活 conda 环境 source $(conda info --base)/etc/profile.d/conda.sh conda activate pump_asd echo "已激活 conda 环境: pump_asd" fi } # ======================================== # 函数:检查进程是否运行 # ======================================== is_running() { if [ -f "$PID_FILE" ]; then PID=$(cat "$PID_FILE") # 检查进程是否存在 if ps -p "$PID" > /dev/null 2>&1; then return 0 # 运行中 fi fi return 1 # 未运行 } # ======================================== # 函数:获取当前PID # ======================================== get_pid() { if [ -f "$PID_FILE" ]; then cat "$PID_FILE" else echo "" fi } # ======================================== # 函数:启动服务 # ======================================== start_service() { # 检查是否已经运行 if is_running; then echo "服务已在运行中, PID: $(get_pid)" echo "如需重启,请使用: ./start.sh restart" return 1 fi # 激活conda环境 activate_conda # 检查必要文件 if [ ! -f "run_pickup_monitor.py" ]; then echo "错误: run_pickup_monitor.py 不存在" exit 1 fi if [ ! -f "config/pickup_config.db" ]; then echo "错误: config/pickup_config.db 不存在" echo "请先运行迁移脚本: python tool/migrate_yaml_to_db.py" exit 1 fi # 创建日志目录 mkdir -p logs # 启动服务 echo "后台运行模式..." # stdout/stderr 丢弃,所有日志由 RotatingFileHandler 写入 logs/system.log nohup python run_pickup_monitor.py > /dev/null 2>&1 & PID=$! echo $PID > "$PID_FILE" # 等待1秒检查是否正常启动 sleep 1 if ps -p "$PID" > /dev/null 2>&1; then echo "服务启动成功, PID: $PID" echo "日志文件: logs/system.log" echo "" echo "查看日志: tail -f logs/system.log" echo "停止服务: ./start.sh stop" echo "重启服务: ./start.sh restart" else echo "服务启动失败,请检查日志: logs/system.log" rm -f "$PID_FILE" return 1 fi } # ======================================== # 函数:停止服务 # ======================================== stop_service() { if ! is_running; then echo "服务未运行" rm -f "$PID_FILE" return 0 fi PID=$(get_pid) echo "正在停止服务, PID: $PID" # 发送 SIGTERM 信号,优雅停止 kill "$PID" 2>/dev/null # 等待进程结束(最多等待10秒) WAIT_COUNT=0 while ps -p "$PID" > /dev/null 2>&1; do if [ $WAIT_COUNT -ge 10 ]; then echo "进程未响应,强制终止..." kill -9 "$PID" 2>/dev/null break fi sleep 1 WAIT_COUNT=$((WAIT_COUNT + 1)) echo "等待进程结束... ($WAIT_COUNT/10)" done rm -f "$PID_FILE" echo "服务已停止" } # ======================================== # 函数:重启服务 # ======================================== restart_service() { echo "==========================================" echo "重启拾音器异响检测服务" echo "==========================================" stop_service echo "" sleep 2 # 等待2秒确保资源完全释放 start_service } # ======================================== # 函数:查看服务状态 # ======================================== show_status() { echo "==========================================" echo "拾音器异响检测服务状态" echo "==========================================" if is_running; then PID=$(get_pid) echo "状态: 运行中" echo "PID: $PID" echo "" # 显示进程信息 echo "进程详情:" ps -p "$PID" -o pid,ppid,user,%cpu,%mem,etime,command | head -2 echo "" # 显示最近日志 echo "最近10行日志:" echo "------------------------------------------" tail -10 logs/system.log 2>/dev/null || echo "(无日志)" else echo "状态: 未运行" if [ -f "$PID_FILE" ]; then echo "注意: PID文件存在但进程已停止,可能是异常退出" rm -f "$PID_FILE" fi fi } # ======================================== # 函数:前台运行 # ======================================== run_foreground() { # 检查是否已经运行 if is_running; then echo "服务已在后台运行中, PID: $(get_pid)" echo "请先停止: ./start.sh stop" return 1 fi # 激活conda环境 activate_conda # 检查必要文件 if [ ! -f "run_pickup_monitor.py" ]; then echo "错误: run_pickup_monitor.py 不存在" exit 1 fi if [ ! -f "config/pickup_config.db" ]; then echo "错误: config/pickup_config.db 不存在" echo "请先运行迁移脚本: python tool/migrate_yaml_to_db.py" exit 1 fi # 创建日志目录 mkdir -p logs echo "前台运行模式..." python run_pickup_monitor.py } # ======================================== # 函数:显示帮助 # ======================================== show_help() { echo "拾音器异响检测系统 - 启动脚本" echo "" echo "用法: ./start.sh [命令]" echo "" echo "命令:" echo " (无参数) 前台运行" echo " -d, --daemon 后台运行" echo " start 后台启动服务" echo " stop 停止服务" echo " restart 重启服务" echo " status 查看服务状态" echo " help 显示帮助信息" echo "" echo "示例:" echo " ./start.sh -d # 后台启动" echo " ./start.sh restart # 重启服务" echo " ./start.sh status # 查看状态" } # ======================================== # 主逻辑 # ======================================== case "$1" in stop) stop_service ;; restart) restart_service ;; status) show_status ;; start|-d|--daemon) start_service ;; help|--help|-h) show_help ;; "") run_foreground ;; *) echo "未知命令: $1" echo "" show_help exit 1 ;; esac