From bed473cd30bfe7fcff1b1f3103e8e6f1cb7e24b5 Mon Sep 17 00:00:00 2001 From: egg Date: Tue, 2 Dec 2025 18:01:24 +0800 Subject: [PATCH] fix: properly stop child processes and orphaned services MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Kill entire process tree (parent + children) when stopping - Add port-based cleanup as fallback for orphaned processes - Remove 'set -e' to allow graceful failure handling - Pass port numbers to stop_service for cleanup 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- start.sh | 57 +++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/start.sh b/start.sh index 9d818dc..efee48b 100755 --- a/start.sh +++ b/start.sh @@ -8,7 +8,7 @@ # ./start.sh --status Show service status # ./start.sh --help Show help -set -e +# Note: We don't use 'set -e' here because stop commands may fail gracefully # Colors GREEN='\033[0;32m' @@ -181,16 +181,47 @@ start_frontend() { fi } +kill_process_tree() { + local pid=$1 + # Kill all child processes first + pkill -TERM -P "$pid" 2>/dev/null || true + # Then kill the parent + kill -TERM "$pid" 2>/dev/null || true +} + +force_kill_process_tree() { + local pid=$1 + # Force kill all child processes + pkill -9 -P "$pid" 2>/dev/null || true + # Force kill the parent + kill -9 "$pid" 2>/dev/null || true +} + +kill_by_port() { + local port=$1 + local pids=$(lsof -ti :$port 2>/dev/null) + if [ -n "$pids" ]; then + echo "$pids" | xargs kill -TERM 2>/dev/null || true + sleep 1 + # Force kill if still running + pids=$(lsof -ti :$port 2>/dev/null) + if [ -n "$pids" ]; then + echo "$pids" | xargs kill -9 2>/dev/null || true + fi + fi +} + stop_service() { local name=$1 local pid_file=$2 + local port=$3 if is_running "$pid_file"; then local pid=$(get_pid "$pid_file") echo -e "${YELLOW}Stopping $name (PID: $pid)...${NC}" - # Try graceful shutdown first - kill -TERM "$pid" 2>/dev/null || true + # Kill the entire process tree + kill_process_tree "$pid" # Wait up to 5 seconds local count=0 @@ -201,20 +232,28 @@ stop_service() { # Force kill if still running if is_running "$pid_file"; then - kill -9 "$pid" 2>/dev/null || true + force_kill_process_tree "$pid" fi rm -f "$pid_file" - echo -e "${GREEN}$name stopped${NC}" - else - echo -e "${YELLOW}$name is not running${NC}" fi + + # Also kill any orphaned processes by port (fallback) + if [ -n "$port" ]; then + local port_pids=$(lsof -ti :$port 2>/dev/null) + if [ -n "$port_pids" ]; then + echo -e "${YELLOW}Cleaning up orphaned processes on port $port...${NC}" + kill_by_port "$port" + fi + fi + + echo -e "${GREEN}$name stopped${NC}" } stop_all() { echo -e "${YELLOW}Stopping all services...${NC}" - stop_service "Backend" "$BACKEND_PID_FILE" - stop_service "Frontend" "$FRONTEND_PID_FILE" + stop_service "Backend" "$BACKEND_PID_FILE" "$BACKEND_PORT" + stop_service "Frontend" "$FRONTEND_PID_FILE" "$FRONTEND_PORT" echo -e "${GREEN}All services stopped${NC}" }