This commit is contained in:
parent
826e54c378
commit
e34897a136
|
|
@ -0,0 +1,24 @@
|
|||
FROM vnc-base
|
||||
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive \
|
||||
VNC_PASSWORD=123456
|
||||
|
||||
# 安装 Snap 版 Chromium
|
||||
RUN snap install chromium \
|
||||
&& ln -s /snap/bin/chromium /usr/local/bin/chromium-browser
|
||||
|
||||
RUN git clone https://github.com/novnc/noVNC.git /opt/novnc \
|
||||
&& git clone https://github.com/novnc/websockify.git /opt/novnc/utils/websockify
|
||||
|
||||
RUN mkdir -p /root/.vnc && echo "$VNC_PASSWORD" | vncpasswd -f > /root/.vnc/passwd && chmod 600 /root/.vnc/passwd
|
||||
|
||||
EXPOSE 6080 9222
|
||||
|
||||
CMD Xvfb :1 -screen 0 1280x1024x24 & \
|
||||
export DISPLAY=:1 && \
|
||||
fluxbox & \
|
||||
vncserver :1 -geometry 1280x1024 -depth 24 -localhost no && \
|
||||
/opt/novnc/utils/novnc_proxy --vnc localhost:5901 --listen 6080 & \
|
||||
chromium-browser --no-sandbox --disable-gpu --remote-debugging-port=9222 --remote-debugging-address=0.0.0.0 --window-size=1280,1024 && \
|
||||
tail -f /dev/null
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
# FROM ubuntu:22.04
|
||||
FROM harbor.hk.crabapples.cn:22580/library/ubuntu:24.04
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive \
|
||||
VNC_PASSWORD=123456
|
||||
|
||||
RUN sed -i 's@//.*archive.ubuntu.com@//mirrors.aliyun.com@g' /etc/apt/sources.list.d/ubuntu.sources &&\
|
||||
sed -i 's@//security.ubuntu.com@//mirrors.aliyun.com@g' /etc/apt/sources.list.d/ubuntu.sources &&\
|
||||
sed -i 's@//ports.ubuntu.com@//mirrors.aliyun.com@g' /etc/apt/sources.list.d/ubuntu.sources
|
||||
|
||||
|
||||
RUN apt-get update
|
||||
|
||||
RUN apt-get install -y wget curl gnupg x11vnc xvfb fluxbox git python3 snapd && rm -rf /var/lib/apt/lists/*
|
||||
150
app.py
150
app.py
|
|
@ -58,7 +58,7 @@ async def start_xvnc_server(instance: int = 1, password: str = "123456") -> str:
|
|||
try:
|
||||
# 调用 browser-vnc.sh 脚本
|
||||
process = await asyncio.create_subprocess_exec(
|
||||
f"{SHELL_DIR}/browser-vnc.sh",
|
||||
f"{SHELL_DIR}/start-vnc.sh",
|
||||
"start",
|
||||
str(instance),
|
||||
password,
|
||||
|
|
@ -139,154 +139,6 @@ async def stop_xvnc_server(instance: int = 1, keep_data: bool = False) -> str:
|
|||
data["message"] = str(e)
|
||||
return json.dumps(data, ensure_ascii=False)
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
async def stop_all_xvnc_servers(keep_data: bool = False) -> str:
|
||||
"""停止所有 VNC 实例
|
||||
|
||||
Args:
|
||||
keep_data: 是否保留用户数据,默认 False(删除所有数据)
|
||||
|
||||
Returns:
|
||||
操作结果
|
||||
"""
|
||||
data = {
|
||||
"status": 200,
|
||||
"action": "stop_all",
|
||||
"keep_data": keep_data
|
||||
}
|
||||
|
||||
try:
|
||||
# 选择命令:stop-all 或 stop-all-keep-data
|
||||
cmd = "stop-all-keep-data" if keep_data else "stop-all"
|
||||
|
||||
process = await asyncio.create_subprocess_exec(
|
||||
f"{SHELL_DIR}/browser-vnc.sh",
|
||||
cmd,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE
|
||||
)
|
||||
|
||||
stdout, stderr = await process.communicate()
|
||||
output = stdout.decode()
|
||||
|
||||
if process.returncode == 0:
|
||||
data["message"] = output
|
||||
else:
|
||||
data["status"] = 500
|
||||
data["message"] = stderr.decode() or output or "Unknown error"
|
||||
|
||||
return json.dumps(data, ensure_ascii=False)
|
||||
|
||||
except Exception as e:
|
||||
data["status"] = 500
|
||||
data["message"] = str(e)
|
||||
return json.dumps(data, ensure_ascii=False)
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
async def list_xvnc_servers() -> str:
|
||||
"""列出所有运行中的 VNC 实例"""
|
||||
data = {
|
||||
"status": 200,
|
||||
"action": "list",
|
||||
"instances": []
|
||||
}
|
||||
|
||||
try:
|
||||
process = await asyncio.create_subprocess_exec(
|
||||
f"{SHELL_DIR}/browser-vnc.sh",
|
||||
"status",
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE
|
||||
)
|
||||
|
||||
stdout, stderr = await process.communicate()
|
||||
output = stdout.decode()
|
||||
|
||||
# 解析输出,提取运行中的实例
|
||||
for line in output.split('\n'):
|
||||
if "✅ Running" in line:
|
||||
# 提取实例编号,例如 "Instance 1: ✅ Running"
|
||||
import re
|
||||
match = re.search(r'Instance (\d+):', line)
|
||||
if match:
|
||||
instance = int(match.group(1))
|
||||
data["instances"].append({
|
||||
"instance": instance,
|
||||
"vnc_port": 5900 + (instance - 1),
|
||||
"display": 98 + instance,
|
||||
"vnc_url": f"{VNC_SERVER_HOST}/vnc_lite.html?path=?token=user{instance}"
|
||||
})
|
||||
|
||||
data["count"] = len(data["instances"])
|
||||
data["raw_output"] = output
|
||||
|
||||
return json.dumps(data, ensure_ascii=False)
|
||||
|
||||
except Exception as e:
|
||||
data["status"] = 500
|
||||
data["message"] = str(e)
|
||||
return json.dumps(data, ensure_ascii=False)
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
async def get_vnc_connection_info(instance: int = 1) -> str:
|
||||
"""获取指定实例的连接信息
|
||||
|
||||
Args:
|
||||
instance: 实例编号 (1-10)
|
||||
|
||||
Returns:
|
||||
包含连接信息的 JSON 字符串
|
||||
"""
|
||||
data = {
|
||||
"instance": instance,
|
||||
"status": 200
|
||||
}
|
||||
|
||||
try:
|
||||
# 检查实例是否在运行
|
||||
process = await asyncio.create_subprocess_exec(
|
||||
f"{SHELL_DIR}/browser-vnc.sh",
|
||||
"status",
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE
|
||||
)
|
||||
|
||||
stdout, _ = await process.communicate()
|
||||
output = stdout.decode()
|
||||
|
||||
# 检查实例状态
|
||||
instance_pattern = f"Instance {instance}:"
|
||||
is_running = False
|
||||
for line in output.split('\n'):
|
||||
if instance_pattern in line:
|
||||
if "✅ Running" in line:
|
||||
is_running = True
|
||||
break
|
||||
|
||||
public_ip = subprocess.getoutput("hostname -I | awk '{print $1}'").strip()
|
||||
vnc_port = 5900 + (instance - 1)
|
||||
display_num = 98 + instance
|
||||
|
||||
data["is_running"] = is_running
|
||||
data["vnc_url"] = f"{VNC_SERVER_HOST}/vnc_lite.html?path=?token=user{instance}"
|
||||
data["vnc_port"] = vnc_port
|
||||
data["display"] = display_num
|
||||
data["public_ip"] = public_ip
|
||||
|
||||
if not is_running:
|
||||
data["warning"] = "Instance is not running, start it with start_xvnc_server"
|
||||
|
||||
return json.dumps(data, ensure_ascii=False)
|
||||
|
||||
except Exception as e:
|
||||
data["status"] = 500
|
||||
data["message"] = str(e)
|
||||
return json.dumps(data, ensure_ascii=False)
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
async def cleanup_xvnc_data(instance: Optional[int] = None) -> str:
|
||||
"""清理 VNC 实例的用户数据
|
||||
|
|
|
|||
|
|
@ -0,0 +1,77 @@
|
|||
#!/bin/bash
|
||||
# 浏览器 VNC 守护进程
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TARGET_URL="https://www.baidu.com"
|
||||
VNC_PWD=${1:-"123456"} # VNC 密码
|
||||
VNC_PORT=${2:-5900} # VNC 端口
|
||||
DISPLAY_NUM=${3:-99} # 显示编号
|
||||
DATA_DIR=${4:-"/tmp/chrome-profile-${DISPLAY_NUM}"} # 用户数据目录
|
||||
PID_FILE="/tmp/chrome-browser-${DISPLAY_NUM}.pid" # 进程 ID 文件
|
||||
LOG_FILE="/tmp/chrome-browser-${DISPLAY_NUM}.log" # 日志文件
|
||||
USER_COUNT="${5:-10}"
|
||||
|
||||
GREEN='\033[0;32m'; RED='\033[0;31m'; NC='\033[0m'
|
||||
log() { echo -e "${GREEN}[$(date '+%H:%M:%S')]${NC} $*"; }
|
||||
err() { echo -e "${RED}[$(date '+%H:%M:%S')]${NC} $*" >&2; }
|
||||
|
||||
# 检查是否已在运行
|
||||
if [ -f "$PID_FILE" ] && kill -0 $(cat "$PID_FILE") 2>/dev/null; then
|
||||
err "实例 :${DISPLAY_NUM} 已在运行中"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cleanup() {
|
||||
log "正在清理实例 :${DISPLAY_NUM}..."
|
||||
pkill -P $$ 2>/dev/null || true
|
||||
pkill -f "Xvfb :${DISPLAY_NUM}" 2>/dev/null || true
|
||||
pkill -f "x11vnc.*${DISPLAY_NUM}" 2>/dev/null || true
|
||||
rm -f "$PID_FILE" 2>/dev/null || true
|
||||
}
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
# 记录当前进程 ID
|
||||
echo $$ > "$PID_FILE"
|
||||
|
||||
log "正在启动 Xvfb :${DISPLAY_NUM}"
|
||||
Xvfb :${DISPLAY_NUM} -screen 0 1280x1024x24 -nolisten tcp &
|
||||
sleep 2
|
||||
export DISPLAY=:${DISPLAY_NUM}
|
||||
|
||||
log "正在启动 Chromium (数据目录: ${DATA_DIR})"
|
||||
mkdir -p "$DATA_DIR"
|
||||
|
||||
# 查找 Chromium 可执行文件
|
||||
CHROME_BIN=$(ls $HOME/.cache/ms-playwright/chromium-*/chrome-linux/chrome 2>/dev/null | head -1)
|
||||
if [ -z "$CHROME_BIN" ]; then
|
||||
CHROME_BIN=$(which chromium-browser 2>/dev/null || which google-chrome-stable 2>/dev/null || true)
|
||||
fi
|
||||
[ -z "$CHROME_BIN" ] && { err "未找到 Chromium"; exit 1; }
|
||||
|
||||
# 启动 Chromium(非 headless 模式,可见界面)
|
||||
"$CHROME_BIN" \
|
||||
--no-sandbox \
|
||||
--disable-gpu \
|
||||
--disable-dev-shm-usage \
|
||||
--user-data-dir="${DATA_DIR}" \
|
||||
--window-size=1280,1024 \
|
||||
"${TARGET_URL}" &
|
||||
|
||||
CHROME_PID=$!
|
||||
|
||||
log "正在启动 x11vnc,端口: ${VNC_PORT}..."
|
||||
x11vnc -display :${DISPLAY_NUM} -forever -shared -passwd ${VNC_PWD} -rfbport ${VNC_PORT} -bg &
|
||||
|
||||
# 获取服务器公网 IP
|
||||
PUBLIC_HOST=$(curl -sf ifconfig.me 2>/dev/null || hostname -I | awk '{print $1}')
|
||||
log "=========================================="
|
||||
log "✅ 浏览器已启动 (仅 VNC,无 CDP)"
|
||||
log "🖥️ VNC 地址: ${PUBLIC_HOST}:${VNC_PORT}"
|
||||
log "🔑 VNC 密码: ${VNC_PWD}"
|
||||
log "📁 数据目录: ${DATA_DIR}"
|
||||
log "🛑 停止命令: ./browser-vnc.sh stop ${DISPLAY_NUM}"
|
||||
log "=========================================="
|
||||
|
||||
# 等待 Chromium 进程结束
|
||||
wait $CHROME_PID 2>/dev/null || true
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
#!/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
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
#!/bin/bash
|
||||
#wget -O- -q --show-progress https://git.nps.crabapples.cn/crabapples/learn-spider/raw/branch/main/bin/auto_install.sh | bash
|
||||
# wget -q --show-progress https://git.nps.crabapples.cn/crabapples/learn-spider/raw/branch/main/bin/close_vnc.sh && chmod +x close_vnc.sh
|
||||
SECOND=5
|
||||
GIT_DOMAIN=https://git.nps.crabapples.cn
|
||||
echo "清理旧脚本..."
|
||||
|
||||
rm -rf ./install.sh ./start_vnc_server.sh ./close_vnc_server.sh ./start_spider.sh ./update.sh ./uninstall.sh
|
||||
echo "开始下载..."
|
||||
|
||||
echo "下载安装脚本..."
|
||||
wget -q --show-progress $GIT_DOMAIN/crabapples/learn-spider/raw/branch/main/bin/install.sh && chmod +x install.sh
|
||||
|
||||
echo "下载启动VNC脚本..."
|
||||
wget -q --show-progress $GIT_DOMAIN/crabapples/learn-spider/raw/branch/main/bin/start_vnc_server.sh && chmod +x start_vnc_server.sh
|
||||
|
||||
echo "下载关闭VNC脚本..."
|
||||
wget -q --show-progress $GIT_DOMAIN/crabapples/learn-spider/raw/branch/main/bin/close_vnc_server.sh && chmod +x close_vnc_server.sh
|
||||
|
||||
echo "下载启动爬虫脚本..."
|
||||
wget -q --show-progress $GIT_DOMAIN/crabapples/learn-spider/raw/branch/main/bin/start_spider.sh && chmod +x start_spider.sh
|
||||
|
||||
echo "下载更新脚本..."
|
||||
wget -q --show-progress $GIT_DOMAIN/crabapples/learn-spider/raw/branch/main/bin/update.sh && chmod +x update.sh
|
||||
|
||||
echo "下载卸载脚本..."
|
||||
wget -q --show-progress $GIT_DOMAIN/crabapples/learn-spider/raw/branch/main/bin/uninstall.sh && chmod +x uninstall.sh
|
||||
|
||||
for i in $(seq 1 $SECOND); do
|
||||
clear
|
||||
echo "脚本下载完成$(($SECOND-$i))S后开始自动安装...."
|
||||
sleep 1
|
||||
done
|
||||
|
||||
USER_COUNT=10
|
||||
# 公共的工作目录
|
||||
PUBLIC_DIR="/shared"
|
||||
# git仓库加速地址
|
||||
GIT_NO_VNC="$GIT_DOMAIN/crabapples/noVNC.git"
|
||||
GIT_WEBSOCKIFY="$GIT_DOMAIN/crabapples/websockify.git"
|
||||
GIT_PY_SPIDER="$GIT_DOMAIN/crabapples/learn-spider.git"
|
||||
|
||||
./install.sh $USER_COUNT $PUBLIC_DIR $GIT_NO_VNC $GIT_WEBSOCKIFY $GIT_PY_SPIDER
|
||||
echo "安装完成"
|
||||
|
||||
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
#!/bin/bash
|
||||
# Browser VNC Manager
|
||||
|
||||
# 浏览器 VNC 管理器
|
||||
|
||||
DAEMON_SCRIPT="$(dirname $0)/start-browser-vnc.sh"
|
||||
BASE_VNC_PORT=5900
|
||||
|
|
@ -14,12 +13,12 @@ start() {
|
|||
local data_dir="${BASE_DATA_DIR}/instance-${instance}"
|
||||
|
||||
if [ -f "/tmp/chrome-browser-${display_num}.pid" ] && kill -0 $(cat "/tmp/chrome-browser-${display_num}.pid") 2>/dev/null; then
|
||||
echo "Instance ${instance} already running"
|
||||
echo "实例 ${instance} 已在运行中"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "Starting instance ${instance} (display :${display_num}, VNC port: ${vnc_port})..."
|
||||
echo "Data directory: ${data_dir}"
|
||||
echo "正在启动实例 ${instance} (显示编号 :${display_num}, VNC 端口: ${vnc_port})..."
|
||||
echo "数据目录: ${data_dir}"
|
||||
|
||||
# 确保数据目录存在
|
||||
mkdir -p "$data_dir"
|
||||
|
|
@ -28,10 +27,10 @@ start() {
|
|||
sleep 3
|
||||
|
||||
local public_ip=$(hostname -I | awk '{print $1}')
|
||||
echo "✅ Instance ${instance} started"
|
||||
echo "✅ 实例 ${instance} 已启动"
|
||||
echo " VNC: ${public_ip}:${vnc_port}"
|
||||
echo " Password: ${vnc_pwd}"
|
||||
echo " Data: ${data_dir} (will be deleted on stop)"
|
||||
echo " 密码: ${vnc_pwd}"
|
||||
echo " 数据: ${data_dir} (停止时将删除)"
|
||||
}
|
||||
|
||||
stop() {
|
||||
|
|
@ -43,7 +42,7 @@ stop() {
|
|||
|
||||
if [ -f "$pid_file" ]; then
|
||||
local pid=$(cat "$pid_file")
|
||||
echo "Stopping instance ${instance} (PID: $pid)..."
|
||||
echo "正在停止实例 ${instance} (PID: $pid)..."
|
||||
|
||||
# 先发送 TERM 信号,让浏览器优雅关闭
|
||||
kill -TERM $pid 2>/dev/null
|
||||
|
|
@ -51,7 +50,7 @@ stop() {
|
|||
|
||||
# 如果还在运行,强制杀死
|
||||
if kill -0 $pid 2>/dev/null; then
|
||||
echo "Force killing..."
|
||||
echo "正在强制终止..."
|
||||
kill -9 $pid 2>/dev/null
|
||||
fi
|
||||
|
||||
|
|
@ -60,17 +59,17 @@ stop() {
|
|||
|
||||
# 删除用户数据目录
|
||||
if [ "$delete_data" = "true" ] && [ -d "$data_dir" ]; then
|
||||
echo "Deleting user data: ${data_dir}"
|
||||
echo "正在删除用户数据: ${data_dir}"
|
||||
rm -rf "$data_dir"
|
||||
fi
|
||||
|
||||
echo "✅ Instance ${instance} stopped"
|
||||
echo "✅ 实例 ${instance} 已停止"
|
||||
else
|
||||
echo "Instance ${instance} not running, cleaning up data..."
|
||||
echo "实例 ${instance} 未运行,正在清理数据..."
|
||||
# 即使进程不在运行,也清理数据目录
|
||||
if [ -d "$data_dir" ] && [ "$delete_data" = "true" ]; then
|
||||
rm -rf "$data_dir"
|
||||
echo "✅ Data cleaned: ${data_dir}"
|
||||
echo "✅ 数据已清理: ${data_dir}"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
|
@ -84,7 +83,7 @@ stop() {
|
|||
}
|
||||
|
||||
status() {
|
||||
echo "=== Browser Instances (VNC only) ==="
|
||||
echo "=== 浏览器实例状态 (仅 VNC) ==="
|
||||
for i in {1..10}; do
|
||||
local display_num=$((98 + i))
|
||||
local pid_file="/tmp/chrome-browser-${display_num}.pid"
|
||||
|
|
@ -92,19 +91,19 @@ status() {
|
|||
|
||||
if [ -f "$pid_file" ] && kill -0 $(cat "$pid_file") 2>/dev/null; then
|
||||
local pid=$(cat "$pid_file")
|
||||
echo "Instance ${i}: ✅ Running (VNC: $((5900 + i - 1)), PID: ${pid}, Data: ${data_dir})"
|
||||
echo "实例 ${i}: ✅ 运行中 (VNC 端口: $((5900 + i - 1)), PID: ${pid}, 数据: ${data_dir})"
|
||||
else
|
||||
echo "Instance ${i}: ❌ Stopped"
|
||||
echo "实例 ${i}: ❌ 已停止"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
stop_all() {
|
||||
echo "Stopping all instances..."
|
||||
echo "正在停止所有实例..."
|
||||
for i in {1..10}; do
|
||||
stop $i "${1:-true}"
|
||||
done
|
||||
echo "✅ All instances stopped"
|
||||
echo "✅ 所有实例已停止"
|
||||
}
|
||||
|
||||
cleanup_data() {
|
||||
|
|
@ -116,23 +115,23 @@ cleanup_data() {
|
|||
|
||||
# 如果还有残留数据,强制删除
|
||||
if [ -d "$data_dir" ]; then
|
||||
echo "Force cleaning data: ${data_dir}"
|
||||
echo "正在强制清理数据: ${data_dir}"
|
||||
rm -rf "$data_dir"
|
||||
fi
|
||||
|
||||
echo "✅ Data for instance ${instance} cleaned"
|
||||
echo "✅ 实例 ${instance} 的数据已清理"
|
||||
}
|
||||
|
||||
cleanup_all_data() {
|
||||
echo "Cleaning all instance data..."
|
||||
echo "正在清理所有实例数据..."
|
||||
for i in {1..10}; do
|
||||
local data_dir="${BASE_DATA_DIR}/instance-${i}"
|
||||
if [ -d "$data_dir" ]; then
|
||||
rm -rf "$data_dir"
|
||||
echo " Removed: ${data_dir}"
|
||||
echo " 已删除: ${data_dir}"
|
||||
fi
|
||||
done
|
||||
echo "✅ All data cleaned"
|
||||
echo "✅ 所有数据已清理"
|
||||
}
|
||||
|
||||
case "${1:-}" in
|
||||
|
|
@ -161,25 +160,25 @@ case "${1:-}" in
|
|||
cleanup_all_data
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|stop-keep-data|stop-all|stop-all-keep-data|status|cleanup|cleanup-all} [instance_num] [password]"
|
||||
echo "用法: $0 {start|stop|stop-keep-data|stop-all|stop-all-keep-data|status|cleanup|cleanup-all} [实例编号] [密码]"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " start [num] [pwd] - Start instance (default: 1, 123456)"
|
||||
echo " stop [num] - Stop and DELETE user data"
|
||||
echo " stop-keep-data [num] - Stop but KEEP user data"
|
||||
echo " stop-all - Stop all and DELETE all user data"
|
||||
echo " stop-all-keep-data - Stop all but KEEP user data"
|
||||
echo " status - Show all instances status"
|
||||
echo " cleanup [num] - Force delete user data for instance"
|
||||
echo " cleanup-all - Force delete all user data"
|
||||
echo "命令说明:"
|
||||
echo " start [编号] [密码] - 启动实例 (默认: 1, 123456)"
|
||||
echo " stop [编号] - 停止并删除用户数据"
|
||||
echo " stop-keep-data [编号] - 停止但保留用户数据"
|
||||
echo " stop-all - 停止所有实例并删除所有数据"
|
||||
echo " stop-all-keep-data - 停止所有实例但保留所有数据"
|
||||
echo " status - 显示所有实例状态"
|
||||
echo " cleanup [编号] - 强制删除指定实例的用户数据"
|
||||
echo " cleanup-all - 强制删除所有实例的用户数据"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " $0 start 1 # Start instance 1 (VNC:5900, password:123456)"
|
||||
echo " $0 start 2 mypass # Start instance 2 (VNC:5901, password:mypass)"
|
||||
echo " $0 stop 1 # Stop instance 1 and DELETE its data"
|
||||
echo " $0 stop-keep-data 1 # Stop instance 1 but KEEP its data"
|
||||
echo " $0 status # Show all instances"
|
||||
echo " $0 cleanup-all # Delete all instance data"
|
||||
echo "使用示例:"
|
||||
echo " $0 start 1 # 启动实例 1 (VNC:5900, 密码:123456)"
|
||||
echo " $0 start 2 mypass # 启动实例 2 (VNC:5901, 密码:mypass)"
|
||||
echo " $0 stop 1 # 停止实例 1 并删除其数据"
|
||||
echo " $0 stop-keep-data 1 # 停止实例 1 但保留其数据"
|
||||
echo " $0 status # 显示所有实例状态"
|
||||
echo " $0 cleanup-all # 删除所有实例数据"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
|
@ -0,0 +1,244 @@
|
|||
#!/bin/bash
|
||||
|
||||
# ==================== 配置变量 ====================
|
||||
# 需要创建的用户数量
|
||||
USER_COUNT=${1:-10}
|
||||
# 公共的工作目录
|
||||
PUBLIC_DIR="${2:-/shared}"
|
||||
# git仓库地址
|
||||
GIT_NO_VNC="${3:-https://github.com/novnc/noVNC.git}"
|
||||
GIT_WEBSOCKIFY="${4:-https://github.com/novnc/websockify.git}"
|
||||
GIT_PY_SPIDER="${5:-https://git.nps.crabapples.cn/crabapples/learn-spider.git}"
|
||||
|
||||
echo "USER_COUNT: $USER_COUNT"
|
||||
echo "PUBLIC_DIR: $PUBLIC_DIR"
|
||||
echo "GIT_NO_VNC: $GIT_NO_VNC"
|
||||
echo "GIT_WEBSOCKIFY: $GIT_WEBSOCKIFY"
|
||||
echo "GIT_PY_SPIDER: $GIT_PY_SPIDER"
|
||||
echo ""
|
||||
sleep 3
|
||||
# ==================== 函数定义 ====================
|
||||
|
||||
# 1. 预安装软件
|
||||
pre_install(){
|
||||
echo "当前进度:01.预安装软件"
|
||||
sudo apt update
|
||||
sudo apt install -y xfce4 xfce4-goodies
|
||||
sudo apt install -y tigervnc-standalone-server tigervnc-common
|
||||
sudo apt install -y git python3 openssl
|
||||
echo "✅ [完成] 预安装软件"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 2. 开放防火墙
|
||||
open_firewall(){
|
||||
echo "当前进度:02.开放防火墙"
|
||||
sudo ufw allow 6080/tcp
|
||||
echo "✅ [完成] 开放防火墙端口 6080"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 3. 批量创建用户
|
||||
batch_create_user(){
|
||||
echo "当前进度:03.创建用户"
|
||||
for i in $(seq 1 $USER_COUNT); do
|
||||
username="user$i"
|
||||
sudo useradd -m -s /bin/bash "$username"
|
||||
echo "$username:$username" | sudo chpasswd
|
||||
echo " ✓ 用户 $username 创建完成,密码: $username"
|
||||
done
|
||||
echo "✅ [完成] 共创建 $USER_COUNT 个用户"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 4. 批量设置VNC密码
|
||||
batch_set_vncpdw(){
|
||||
echo "当前进度:04.设置VNC密码"
|
||||
for i in $(seq 1 $USER_COUNT); do
|
||||
username="user$i"
|
||||
sudo su - "$username" -c "mkdir -p ~/.vnc && echo '$username' | vncpasswd -f > ~/.vnc/passwd && chmod 600 ~/.vnc/passwd"
|
||||
echo " ✓ 正在设置 $username 的VNC密码"
|
||||
done
|
||||
echo "✅ [完成] 所有VNC密码设置完成"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 5. 创建 VNC 启动配置
|
||||
create_xstartup(){
|
||||
echo "当前进度:05.创建VNC启动配置"
|
||||
for i in $(seq 1 ${USER_COUNT}); do
|
||||
username="user$i"
|
||||
sudo bash -c "cat > /home/$username/.vnc/xstartup << 'EOF'
|
||||
#!/bin/sh
|
||||
unset SESSION_MANAGER
|
||||
unset DBUS_SESSION_BUS_ADDRESS
|
||||
startxfce4 &
|
||||
wait
|
||||
EOF"
|
||||
sudo chmod +x "/home/$username/.vnc/xstartup"
|
||||
echo " ✓ 已创建 $username 的 xstartup"
|
||||
done
|
||||
echo "✅ [完成] 所有用户的 VNC 启动配置创建完成"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 6. 创建公共目录
|
||||
cerate_public_dir(){
|
||||
echo "当前进度:06.创建公共工作目录"
|
||||
sudo mkdir -p "$PUBLIC_DIR"
|
||||
sudo chmod 777 "$PUBLIC_DIR"
|
||||
sudo chmod +t "$PUBLIC_DIR"
|
||||
sudo chown root:root "$PUBLIC_DIR"
|
||||
echo " 公共文件夹已创建: $PUBLIC_DIR"
|
||||
echo " 权限: $(ls -ld $PUBLIC_DIR)"
|
||||
echo "✅ [完成] 公共工作目录创建完成"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 7. 在每个用户home目录创建软连接
|
||||
create_shortcut_for_users(){
|
||||
echo "当前进度:07.创建公共工作目录软连接"
|
||||
for i in $(seq 1 $USER_COUNT); do
|
||||
username="user$i"
|
||||
sudo su - "$username" -c "ln -sf $PUBLIC_DIR ~/workspace"
|
||||
echo " ✓ 正在创建 $username 的快捷方式"
|
||||
done
|
||||
echo "✅ [完成] 所有用户的软连接创建完成"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 8. 准备novnc文件
|
||||
install_vnc_server(){
|
||||
echo "当前进度:08.下载NoVNC源码"
|
||||
cd $PUBLIC_DIR
|
||||
sudo git clone $GIT_NO_VNC
|
||||
sudo git clone $GIT_WEBSOCKIFY
|
||||
echo "✅ [完成] NoVNC 源码下载完成"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 9. 生成ssl证书
|
||||
create_ssl_cert(){
|
||||
echo "当前进度:09.生成SSL证书,有效期:10年"
|
||||
cd $PUBLIC_DIR/noVNC
|
||||
sudo openssl req -new -x509 -days 3650 -nodes \
|
||||
-out self.pem \
|
||||
-keyout self.pem \
|
||||
-subj "/C=CN/ST=Beijing/L=Beijing/O=Test/CN=localhost"
|
||||
echo "✅ [完成] SSL证书生成完成"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 10. 预安装爬虫
|
||||
pre_install_spider(){
|
||||
echo "当前进度:10.下载爬虫源码"
|
||||
cd $PUBLIC_DIR
|
||||
if [ -d "learn-spider" ]; then
|
||||
cd learn-spider
|
||||
sudo git pull
|
||||
else
|
||||
sudo git clone $GIT_PY_SPIDER
|
||||
cd learn-spider
|
||||
fi
|
||||
sudo chmod +x ./pre_install_spider.sh
|
||||
sudo chmod +x ./start_spider.sh
|
||||
sudo ./pre_install_spider.sh
|
||||
echo "✅ [完成] 爬虫环境安装完成"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 11. 创建 token.conf 配置文件
|
||||
create_token_conf(){
|
||||
echo "当前进度:11.创建token.conf配置文件"
|
||||
sudo tee "$PUBLIC_DIR/websockify/token.conf" > /dev/null << EOF
|
||||
# noVNC Token Configuration
|
||||
$(for i in $(seq 1 $USER_COUNT); do echo "user$i: 127.0.0.1:$((5900 + i))"; done)
|
||||
EOF
|
||||
sudo chmod 644 "$PUBLIC_DIR/websockify/token.conf"
|
||||
echo " token.conf 内容预览:"
|
||||
sudo cat "$PUBLIC_DIR/websockify/token.conf" | head -5
|
||||
echo "✅ [完成] token.conf 已创建"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 12. 创建novnc服务文件
|
||||
create_novnc_service(){
|
||||
echo "当前进度:12.创建novnc.service服务配置文件"
|
||||
WEB_ROOT="$PUBLIC_DIR/noVNC"
|
||||
WORKSPACE="$PUBLIC_DIR/websockify"
|
||||
TOKEN_FILE="$WORKSPACE/token.conf"
|
||||
CERT_PATH="$WEB_ROOT/self.pem"
|
||||
SERVICE_FILE="/etc/systemd/system/novnc.service"
|
||||
|
||||
sudo tee "$SERVICE_FILE" > /dev/null << EOF
|
||||
[Unit]
|
||||
Description=noVNC WebSocket Proxy
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=$WORKSPACE
|
||||
ExecStart=$WORKSPACE/run \
|
||||
--web $WEB_ROOT \
|
||||
--target-config $TOKEN_FILE \
|
||||
--cert $CERT_PATH \
|
||||
6080
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl stop novnc 2>/dev/null
|
||||
sudo systemctl enable novnc.service --now
|
||||
|
||||
echo " 服务状态检查:"
|
||||
sudo systemctl status novnc --no-pager | head -5
|
||||
echo "✅ [完成] noVNC 服务已创建并启动"
|
||||
echo " 查看日志: sudo journalctl -u novnc -f"
|
||||
echo " 访问地址: https://$(hostname -I | awk '{print $1}'):6080/vnc.html"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 13. 显示部署总结
|
||||
show_summary(){
|
||||
echo "==================== 部署总结 ===================="
|
||||
echo "✅ 用户数量: $USER_COUNT"
|
||||
echo "✅ 公共目录: $PUBLIC_DIR"
|
||||
echo "✅ VNC 端口范围: 5901-$((5900 + $USER_COUNT))"
|
||||
echo "✅ noVNC 访问地址: https://$(hostname -I | awk '{print $1}'):6080/vnc.html"
|
||||
echo "✅ Token 配置: user1-user$USER_COUNT 使用对应密码"
|
||||
echo ""
|
||||
echo "==================== 部署完成 ===================="
|
||||
}
|
||||
|
||||
# ==================== 主执行流程 ====================
|
||||
|
||||
main(){
|
||||
echo ""
|
||||
echo "========== 开始部署 VNC 环境 =========="
|
||||
echo "开始时间: $(date '+%Y-%m-%d %H:%M:%S')"
|
||||
echo ""
|
||||
|
||||
pre_install
|
||||
open_firewall
|
||||
batch_create_user
|
||||
batch_set_vncpdw
|
||||
create_xstartup
|
||||
cerate_public_dir
|
||||
create_shortcut_for_users
|
||||
install_vnc_server
|
||||
create_ssl_cert
|
||||
pre_install_spider
|
||||
create_token_conf
|
||||
create_novnc_service
|
||||
show_summary
|
||||
|
||||
echo "结束时间: $(date '+%Y-%m-%d %H:%M:%S')"
|
||||
echo ""
|
||||
}
|
||||
|
||||
main
|
||||
|
|
@ -1,15 +1,15 @@
|
|||
#!/bin/bash
|
||||
# Browser VNC Daemon
|
||||
# 浏览器 VNC 守护进程
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TARGET_URL="https://www.baidu.com"
|
||||
VNC_PWD=${1:-"123456"}
|
||||
VNC_PORT=${2:-5900}
|
||||
DISPLAY_NUM=${3:-99}
|
||||
VNC_PWD=${1:-"123456"} # VNC 密码
|
||||
VNC_PORT=${2:-5900} # VNC 端口
|
||||
DISPLAY_NUM=${3:-99} # 显示编号
|
||||
DATA_DIR=${4:-"/tmp/chrome-profile-${DISPLAY_NUM}"} # 用户数据目录
|
||||
PID_FILE="/tmp/chrome-browser-${DISPLAY_NUM}.pid"
|
||||
LOG_FILE="/tmp/chrome-browser-${DISPLAY_NUM}.log"
|
||||
PID_FILE="/tmp/chrome-browser-${DISPLAY_NUM}.pid" # 进程 ID 文件
|
||||
LOG_FILE="/tmp/chrome-browser-${DISPLAY_NUM}.log" # 日志文件
|
||||
|
||||
GREEN='\033[0;32m'; RED='\033[0;31m'; NC='\033[0m'
|
||||
log() { echo -e "${GREEN}[$(date '+%H:%M:%S')]${NC} $*"; }
|
||||
|
|
@ -17,12 +17,12 @@ err() { echo -e "${RED}[$(date '+%H:%M:%S')]${NC} $*" >&2; }
|
|||
|
||||
# 检查是否已在运行
|
||||
if [ -f "$PID_FILE" ] && kill -0 $(cat "$PID_FILE") 2>/dev/null; then
|
||||
err "Instance :${DISPLAY_NUM} already running"
|
||||
err "实例 :${DISPLAY_NUM} 已在运行中"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cleanup() {
|
||||
log "Cleaning up instance :${DISPLAY_NUM}..."
|
||||
log "正在清理实例 :${DISPLAY_NUM}..."
|
||||
pkill -P $$ 2>/dev/null || true
|
||||
pkill -f "Xvfb :${DISPLAY_NUM}" 2>/dev/null || true
|
||||
pkill -f "x11vnc.*${DISPLAY_NUM}" 2>/dev/null || true
|
||||
|
|
@ -30,21 +30,25 @@ cleanup() {
|
|||
}
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
# 记录当前进程 ID
|
||||
echo $$ > "$PID_FILE"
|
||||
|
||||
log "Starting Xvfb :${DISPLAY_NUM}"
|
||||
log "正在启动 Xvfb :${DISPLAY_NUM}"
|
||||
Xvfb :${DISPLAY_NUM} -screen 0 1280x1024x24 -nolisten tcp &
|
||||
sleep 2
|
||||
export DISPLAY=:${DISPLAY_NUM}
|
||||
|
||||
log "Starting Chromium (data dir: ${DATA_DIR})"
|
||||
log "正在启动 Chromium (数据目录: ${DATA_DIR})"
|
||||
mkdir -p "$DATA_DIR"
|
||||
|
||||
# 查找 Chromium 可执行文件
|
||||
CHROME_BIN=$(ls $HOME/.cache/ms-playwright/chromium-*/chrome-linux/chrome 2>/dev/null | head -1)
|
||||
if [ -z "$CHROME_BIN" ]; then
|
||||
CHROME_BIN=$(which chromium-browser 2>/dev/null || which google-chrome-stable 2>/dev/null || true)
|
||||
fi
|
||||
[ -z "$CHROME_BIN" ] && { err "Chromium not found"; exit 1; }
|
||||
[ -z "$CHROME_BIN" ] && { err "未找到 Chromium"; exit 1; }
|
||||
|
||||
# 启动 Chromium(非 headless 模式,可见界面)
|
||||
"$CHROME_BIN" \
|
||||
--no-sandbox \
|
||||
--disable-gpu \
|
||||
|
|
@ -55,16 +59,18 @@ fi
|
|||
|
||||
CHROME_PID=$!
|
||||
|
||||
log "Starting x11vnc on port ${VNC_PORT}..."
|
||||
log "正在启动 x11vnc,端口: ${VNC_PORT}..."
|
||||
x11vnc -display :${DISPLAY_NUM} -forever -shared -passwd ${VNC_PWD} -rfbport ${VNC_PORT} -bg &
|
||||
|
||||
# 获取服务器公网 IP
|
||||
PUBLIC_HOST=$(curl -sf ifconfig.me 2>/dev/null || hostname -I | awk '{print $1}')
|
||||
log "=========================================="
|
||||
log "✅ Browser started (VNC only, no CDP)"
|
||||
log "🖥️ VNC: ${PUBLIC_HOST}:${VNC_PORT}"
|
||||
log "🔑 Password: ${VNC_PWD}"
|
||||
log "📁 Data: ${DATA_DIR}"
|
||||
log "🛑 Stop: ./browser-vnc.sh stop ${DISPLAY_NUM}"
|
||||
log "✅ 浏览器已启动 (仅 VNC,无 CDP)"
|
||||
log "🖥️ VNC 地址: ${PUBLIC_HOST}:${VNC_PORT}"
|
||||
log "🔑 VNC 密码: ${VNC_PWD}"
|
||||
log "📁 数据目录: ${DATA_DIR}"
|
||||
log "🛑 停止命令: ./browser-vnc.sh stop ${DISPLAY_NUM}"
|
||||
log "=========================================="
|
||||
|
||||
# 等待 Chromium 进程结束
|
||||
wait $CHROME_PID 2>/dev/null || true
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/bash
|
||||
spider_code=$1
|
||||
index=$2
|
||||
PUBLIC_DIR="${2:-/shared}"
|
||||
export DISPLAY=:$index
|
||||
echo "当前显示桌面:$DISPLAY"
|
||||
start_spider(){
|
||||
echo "正在启动爬虫$spider_code"
|
||||
if [ "$spider_code" = "01" ]; then
|
||||
spider_name="china_net.py"
|
||||
elif [ "$spider_code" = "02" ]; then
|
||||
spider_name="mail_qq.py"
|
||||
else
|
||||
echo "爬虫名称错误"
|
||||
exit -1
|
||||
fi
|
||||
echo "爬虫名称:$spider_name"
|
||||
.venv/bin/python3.12 "spider/$spider_name"
|
||||
}
|
||||
|
||||
echo "启动爬虫"
|
||||
cd $PUBLIC_DIR/learn-spider
|
||||
echo "$PUBLIC_DIR/learn-spider"
|
||||
start_spider
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
#!/bin/bash
|
||||
USER_COUNT="${1:-10}"
|
||||
PUBLIC_DIR="${2:-/shared}"
|
||||
SECOND="${3:-5}"
|
||||
|
||||
batch_kill_process(){
|
||||
echo "正在结束进程"
|
||||
for i in $(seq 1 $USER_COUNT); do
|
||||
username="user$i"
|
||||
# 杀死用户所有进程
|
||||
sudo pkill -u "$username" 2>/dev/null
|
||||
done
|
||||
echo "进程结束完成"
|
||||
}
|
||||
|
||||
batch_delete_user(){
|
||||
for i in $(seq 1 $USER_COUNT); do
|
||||
username="user$i"
|
||||
# 杀死用户所有进程
|
||||
sudo userdel -r "$username" 2>/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "已删除用户: $username"
|
||||
else
|
||||
echo "用户 $username 不存在,跳过"
|
||||
fi
|
||||
done
|
||||
echo "批量删除完成!"
|
||||
}
|
||||
|
||||
for i in $(seq 1 $SECOND); do
|
||||
clear
|
||||
echo "$(($SECOND-$i))S后开始数据清理...."
|
||||
sleep 1
|
||||
done
|
||||
|
||||
batch_kill_process
|
||||
sleep 5
|
||||
batch_delete_user
|
||||
sudo rm -rf $PUBLIC_DIR
|
||||
echo "数据清理完成"
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
#!/bin/bash
|
||||
|
||||
PUBLIC_DIR="${1:-/shared}"
|
||||
GIT_PY_SPIDER="${2:-https://git.nps.crabapples.cn}"
|
||||
echo "开始更新爬虫"
|
||||
cd $PUBLIC_DIR
|
||||
if [ -d "learn-spider" ]; then
|
||||
cd learn-spider
|
||||
sudo git pull
|
||||
else
|
||||
sudo git clone $GIT_PY_SPIDER
|
||||
cd learn-spider
|
||||
fi
|
||||
|
||||
sudo chmod +x ./pre_install_spider.sh ./start_spider.sh
|
||||
sudo ./pre_install_spider.sh
|
||||
echo "✅ [完成] 爬虫更新完成"
|
||||
Loading…
Reference in New Issue