#!/bin/bash # ============================================ # Flutter Learning 项目启动/关闭脚本 # ============================================ APP_NAME="flutter_learning" APP_DIR="$(cd "$(dirname "$0")" && pwd)" PORT="${PORT:-3031}" LOG_FILE="$APP_DIR/app.log" PID_FILE="$APP_DIR/app.pid" start() { if [ -f "$PID_FILE" ]; then pid=$(cat "$PID_FILE") if kill -0 "$pid" 2>/dev/null; then echo "❌ 服务已在运行中 (PID: $pid)" echo " 如需重启请先执行: $0 stop" exit 1 else rm -f "$PID_FILE" fi fi echo "🚀 正在启动 $APP_NAME ..." echo " 端口: $PORT" echo " 日志: $LOG_FILE" cd "$APP_DIR" || exit 1 nohup npm start > "$LOG_FILE" 2>&1 & pid=$! echo "$pid" > "$PID_FILE" sleep 2 if kill -0 "$pid" 2>/dev/null; then echo "✅ 启动成功 (PID: $pid)" else echo "❌ 启动失败,请查看日志: tail -f $LOG_FILE" rm -f "$PID_FILE" fi } stop() { if [ ! -f "$PID_FILE" ]; then echo "⚠️ 未找到 PID 文件,尝试通过端口查找进程..." pid=$(lsof -ti :"$PORT" 2>/dev/null) if [ -z "$pid" ]; then echo "❌ 未找到运行中的服务" exit 1 fi else pid=$(cat "$PID_FILE") fi echo "🛑 正在停止 $APP_NAME (PID: $pid) ..." kill "$pid" 2>/dev/null sleep 1 if kill -0 "$pid" 2>/dev/null; then echo " 强制终止中..." kill -9 "$pid" 2>/dev/null sleep 1 fi if ! kill -0 "$pid" 2>/dev/null; then echo "✅ 已停止" rm -f "$PID_FILE" else echo "❌ 停止失败" fi } status() { if [ -f "$PID_FILE" ]; then pid=$(cat "$PID_FILE") if kill -0 "$pid" 2>/dev/null; then echo "✅ $APP_NAME 正在运行 (PID: $pid, 端口: $PORT)" return 0 else echo "⚠️ 发现残留 PID 文件,但进程不存在" rm -f "$PID_FILE" fi fi pid=$(lsof -ti :"$PORT" 2>/dev/null) if [ -n "$pid" ]; then echo "⚠️ 端口 $PORT 被其他进程占用 (PID: $pid, 命令: $(ps -p "$pid" -o comm= 2>/dev/null))" else echo "❌ $APP_NAME 未运行" fi } restart() { stop sleep 1 start } case "${1:-start}" in start) start ;; stop) stop ;; restart) restart ;; status) status ;; *) echo "用法: $0 {start|stop|restart|status}" echo "" echo " start - 后台启动服务 (默认)" echo " stop - 停止服务" echo " restart - 重启服务" echo " status - 查看服务状态" echo "" echo "环境变量:" echo " PORT - 监听端口 (默认: 3031)" exit 1 ;; esac