#!/bin/bash # 浏览器 VNC 管理器 DAEMON_SCRIPT="$(dirname $0)/start-browser-vnc.sh" BASE_VNC_PORT=5900 BASE_DATA_DIR="/tmp/chrome-profiles" # 用户数据目录 start() { local instance=${1:-1} local vnc_pwd=${2} # 密码必须传入,不再有默认值 local display_num=$((98 + instance)) local vnc_port=$((BASE_VNC_PORT + instance - 1)) local data_dir="${BASE_DATA_DIR}/instance-${instance}" # 检查密码是否提供 if [ -z "$vnc_pwd" ]; then echo "❌ 错误: 启动实例时必须提供密码" echo "用法: $0 start <实例编号> <密码>" return 1 fi if [ -f "/tmp/chrome-browser-${display_num}.pid" ] && kill -0 $(cat "/tmp/chrome-browser-${display_num}.pid") 2>/dev/null; then echo "实例 ${instance} 已在运行中" return 1 fi echo "正在启动实例 ${instance} (显示编号 :${display_num}, VNC 端口: ${vnc_port})..." echo "数据目录: ${data_dir}" # 确保数据目录存在 mkdir -p "$data_dir" nohup "$DAEMON_SCRIPT" "$vnc_pwd" "$vnc_port" "$display_num" "$data_dir" >> "/tmp/chrome-browser-${display_num}.log" 2>&1 & sleep 3 local public_ip=$(hostname -I | awk '{print $1}') echo "✅ 实例 ${instance} 已启动" echo " VNC: ${public_ip}:${vnc_port}" echo " 密码: ${vnc_pwd}" echo " 数据: ${data_dir} (停止时将删除)" } stop() { local instance=${1:-1} local display_num=$((98 + instance)) local pid_file="/tmp/chrome-browser-${display_num}.pid" local data_dir="${BASE_DATA_DIR}/instance-${instance}" if [ -f "$pid_file" ]; then local pid=$(cat "$pid_file") echo "正在停止实例 ${instance} (PID: $pid)..." # 先发送 TERM 信号,让浏览器优雅关闭 kill -TERM $pid 2>/dev/null sleep 3 # 如果还在运行,强制杀死 if kill -0 $pid 2>/dev/null; then echo "正在强制终止..." kill -9 $pid 2>/dev/null fi # 删除 PID 文件 rm -f "$pid_file" # 删除用户数据目录 if [ -d "$data_dir" ]; then echo "正在删除用户数据: ${data_dir}" rm -rf "$data_dir" fi echo "✅ 实例 ${instance} 已停止" else echo "实例 ${instance} 未运行,正在清理数据..." # 即使进程不在运行,也清理数据目录 if [ -d "$data_dir" ]; then rm -rf "$data_dir" echo "✅ 数据已清理: ${data_dir}" fi fi # 额外清理:杀掉可能残留的 Xvfb 和 x11vnc 进程 pkill -f "Xvfb :${display_num}" 2>/dev/null pkill -f "x11vnc.*${display_num}" 2>/dev/null # 清理临时文件 rm -f "/tmp/.X${display_num}-lock" 2>/dev/null rm -f "/tmp/.X11-unix/X${display_num}" 2>/dev/null } cleanup_data() { local instance=${1:-1} local data_dir="${BASE_DATA_DIR}/instance-${instance}" # 先停止实例 stop $instance # 如果还有残留数据,强制删除 if [ -d "$data_dir" ]; then echo "正在强制清理数据: ${data_dir}" rm -rf "$data_dir" fi echo "✅ 实例 ${instance} 的数据已清理" } case "${1:-}" in start) if [ $# -lt 3 ]; then echo "❌ 错误: start 命令需要实例编号和密码" echo "用法: $0 start <实例编号> <密码>" echo "示例: $0 start 1 mypassword" exit 1 fi start "$2" "$3" ;; stop) stop "${2:-1}" ;; cleanup) cleanup_data "${2:-1}" ;; *) echo "用法: $0 {start|stop|cleanup} [参数]" echo "" echo "命令说明:" echo " start <编号> <密码> - 启动实例 (必须提供密码)" echo " stop [编号] - 停止实例并删除用户数据 (默认: 1)" echo " cleanup [编号] - 强制删除指定实例的用户数据 (默认: 1)" echo "" echo "使用示例:" echo " $0 start 1 mypass # 启动实例 1,密码 mypass" echo " $0 start 2 123456 # 启动实例 2,密码 123456" echo " $0 stop 1 # 停止实例 1 并删除其数据" exit 1 ;; esac