| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- #!/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
|