Files
script/ai/hwaishell.sh
T
chaos a6fbf3c175 修复管道执行模式:支持 curl | bash 非交互式部署
- 新增 is_piped() 检测 stdin 是否为 tty
- 新增 read_or_default() 函数,管道模式下自动使用环境变量或默认值
- 所有 read -p 交互式输入替换为 read_or_default
- 支持环境变量覆盖: GATEWAY_PORT/REMOTE_PORT/APPEND_FRP/USE_VENV/INSTALL_FRP
- 修复 curl | bash 执行时 read 导致端口验证失败的 bug
2026-07-02 14:45:47 +08:00

712 lines
24 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# ================= 颜色定义 =================
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;36m'
PLAIN='\033[0m'
# ================= 工具函数 =================
log_info() { echo -e "${GREEN}[INFO]${PLAIN} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${PLAIN} $1"; }
log_error() { echo -e "${RED}[ERROR]${PLAIN} $1"; }
log_step() { echo -e "\n${BLUE}[${1}]${PLAIN} ${2}"; }
# 检测是否在管道中运行(stdin 不是 tty)
is_piped() {
[ ! -t 0 ]
}
# 交互式读取或自动使用默认值
read_or_default() {
local prompt_msg="$1"
local default_value="$2"
local var_name="$3"
if is_piped; then
# 管道模式:检查环境变量,否则使用默认值
local env_val="${!var_name}"
if [ -n "$env_val" ]; then
echo "$env_val"
else
echo "$default_value"
fi
else
# 交互模式:正常 read
read -p "$prompt_msg" input_val
echo "${input_val:-$default_value}"
fi
}
has_systemd() {
[ -d /run/systemd/system ] || [ -d /var/run/systemd/system ] || systemctl --version &>/dev/null
}
# 安全的进程启动(支持 systemd 和 nohup 两种模式)
safe_start_service() {
local name=$1
local cmd=$2
local service_file=$3
if has_systemd; then
systemctl daemon-reload 2>/dev/null
systemctl enable "$name" --now 2>/dev/null
log_info "$name 已通过 systemd 启动"
else
# 容器/无 systemd 环境:使用 nohup + 简单的 PID 文件管理
local pid_file="/var/run/${name}.pid"
if [ -f "$pid_file" ] && kill -0 "$(cat "$pid_file")" 2>/dev/null; then
log_warn "$name 已在运行 (PID: $(cat "$pid_file"))"
return 0
fi
nohup $cmd > "/var/log/${name}.log" 2>&1 &
echo $! > "$pid_file"
log_info "$name 已通过 nohup 启动 (PID: $!)"
fi
}
# 检查服务状态
get_service_status() {
local name=$1
if has_systemd; then
systemctl is-active "$name" 2>/dev/null || echo "unknown"
else
local pid_file="/var/run/${name}.pid"
if [ -f "$pid_file" ] && kill -0 "$(cat "$pid_file")" 2>/dev/null; then
echo "active (nohup, PID: $(cat "$pid_file"))"
else
echo "inactive"
fi
fi
}
# 重启服务
restart_service() {
local name=$1
if has_systemd; then
systemctl restart "$name" 2>/dev/null
else
local pid_file="/var/run/${name}.pid"
[ -f "$pid_file" ] && kill "$(cat "$pid_file")" 2>/dev/null
sleep 1
fi
}
echo -e "${BLUE}==================================================${PLAIN}"
echo -e "${GREEN} 华为云 Token 动态网关 (6小时高能效缓存版) 部署 ${PLAIN}"
echo -e "${BLUE}==================================================${PLAIN}"
# 1. 检查权限
if [ "$EUID" -ne 0 ]; then
log_error "请使用 root 用户运行此脚本!"
exit 1
fi
# 检测环境类型
IS_CONTAINER=false
if [ -f /.dockerenv ] || grep -qE 'docker|containerd|kubepods' /proc/1/cgroup 2>/dev/null; then
IS_CONTAINER=true
log_warn "检测到容器环境,将使用 nohup 模式替代 systemd"
fi
# ================= 检测并安装 frpc =================
log_step "1/5" "正在检测 frpc 环境..."
if ! command -v frpc &>/dev/null && [ ! -f "/usr/local/bin/frpc" ] && [ ! -f "/usr/bin/frpc" ]; then
log_warn "未检测到 frpc"
INSTALL_FRP=$(read_or_default "是否需要为您自动下载并安装最新版 frpc (使用国内加速镜像)? (y/n, 默认 y): " "y" "INSTALL_FRP")
if [[ "$INSTALL_FRP" == "y" || "$INSTALL_FRP" == "Y" ]]; then
ARCH=$(uname -m)
case "$ARCH" in
x86_64) FRP_ARCH="amd64" ;;
aarch64) FRP_ARCH="arm64" ;;
armv7l) FRP_ARCH="arm" ;;
i386|i686) FRP_ARCH="386" ;;
*)
log_error "不支持的系统架构 $ARCH,请手动安装 frpc。"
exit 1
;;
esac
FRP_VERSION="0.61.0"
log_info "开始通过国内节点下载 frpc v${FRP_VERSION} (${FRP_ARCH})..."
# 使用多个镜像源,自动回退
MIRRORS=(
"https://ghfast.top/https://github.com/fatedier/frp/releases/download/v${FRP_VERSION}/frp_${FRP_VERSION}_linux_${FRP_ARCH}.tar.gz"
"https://mirror.ghproxy.com/https://github.com/fatedier/frp/releases/download/v${FRP_VERSION}/frp_${FRP_VERSION}_linux_${FRP_ARCH}.tar.gz"
"https://github.moeyy.xyz/https://github.com/fatedier/frp/releases/download/v${FRP_VERSION}/frp_${FRP_VERSION}_linux_${FRP_ARCH}.tar.gz"
)
DOWNLOADED=false
for url in "${MIRRORS[@]}"; do
log_info "尝试下载: $url"
if wget --timeout=30 --tries=2 --no-check-certificate -O frp.tar.gz "$url" 2>/dev/null; then
DOWNLOADED=true
break
fi
done
if [ "$DOWNLOADED" != "true" ]; then
log_error "所有镜像源下载失败!请检查网络或手动安装 frpc。"
exit 1
fi
tar -zxf frp.tar.gz > /dev/null 2>&1 || { log_error "解压失败"; exit 1; }
cd frp_${FRP_VERSION}_linux_${FRP_ARCH} || { log_error "无法进入解压目录"; exit 1; }
cp frpc /usr/local/bin/ && chmod +x /usr/local/bin/frpc
mkdir -p /etc/frp
if [ ! -f "/etc/frp/frpc.toml" ]; then
cat << 'FRPCFG' > /etc/frp/frpc.toml
serverAddr = "x.x.x.x"
serverPort = 7000
auth.method = "token"
auth.token = "your_token_here"
FRPCFG
log_warn "已生成 frpc 配置模板,请编辑 /etc/frp/frpc.toml 填入正确的服务器信息"
fi
# 生成 systemd 服务文件(即使当前无 systemd,也保留以便后续使用)
cat << 'FRPSVC' > /etc/systemd/system/frpc.service
[Unit]
Description=Frp Client Service
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
Restart=on-failure
RestartSec=5s
StartLimitInterval=60s
StartLimitBurst=3
ExecStart=/usr/local/bin/frpc -c /etc/frp/frpc.toml
ExecReload=/usr/local/bin/frpc reload -c /etc/frp/frpc.toml
[Install]
WantedBy=multi-user.target
FRPSVC
if has_systemd; then
systemctl daemon-reload && systemctl enable frpc --now
fi
cd .. && rm -rf frp_${FRP_VERSION}_linux_${FRP_ARCH} frp.tar.gz
log_info "frpc 安装完成!配置文件位于 /etc/frp/frpc.toml"
fi
else
log_info "系统已安装 frpc。"
fi
# ================= 配置网关与映射端口 =================
log_step "2/5" "配置动态网关参数:"
GATEWAY_PORT=$(read_or_default "请输入 Python 动态网关的本地监听端口 (默认 8080): " "8080" "GATEWAY_PORT")
REMOTE_PORT=$(read_or_default "请输入你想在 frps 公网端暴露的端口 (默认 18000): " "18000" "REMOTE_PORT")
# 端口有效性检查
if ! [[ "$GATEWAY_PORT" =~ ^[0-9]+$ ]] || [ "$GATEWAY_PORT" -lt 1 ] || [ "$GATEWAY_PORT" -gt 65535 ]; then
log_error "无效的本地端口: $GATEWAY_PORT"
exit 1
fi
if ! [[ "$REMOTE_PORT" =~ ^[0-9]+$ ]] || [ "$REMOTE_PORT" -lt 1 ] || [ "$REMOTE_PORT" -gt 65535 ]; then
log_error "无效的远程端口: $REMOTE_PORT"
exit 1
fi
# ================= 查找 frpc 配置文件 =================
log_step "3/5" "检测 frpc 配置文件位置以追加代理规则:"
FRPC_CONFIG=""
FRPC_TYPE=""
# 按优先级查找配置文件
for path in "/etc/frp/frpc.toml" "/etc/frp/frpc.ini" "/usr/local/etc/frp/frpc.toml" "/usr/local/etc/frp/frpc.ini"; do
if [ -f "$path" ]; then
FRPC_CONFIG="$path"
[[ "$path" == *.toml ]] && FRPC_TYPE="toml" || FRPC_TYPE="ini"
break
fi
done
# 如果没找到,尝试搜索(限制深度避免长时间等待)
if [ -z "$FRPC_CONFIG" ]; then
FRPC_PATH_SEARCH=$(find /etc /usr/local/etc /opt /home -maxdepth 3 \( -name "frpc.toml" -o -name "frpc.ini" \) 2>/dev/null | head -n 1)
if [ -n "$FRPC_PATH_SEARCH" ]; then
FRPC_CONFIG="$FRPC_PATH_SEARCH"
[[ "$FRPC_PATH_SEARCH" == *.toml ]] && FRPC_TYPE="toml" || FRPC_TYPE="ini"
fi
fi
APPEND_FRP="n"
if [ -n "$FRPC_CONFIG" ]; then
log_info "识别到 frpc 配置: $FRPC_CONFIG (${FRPC_TYPE})"
APPEND_FRP=$(read_or_default "是否自动将华为云转发规则追加到该文件? (y/n, 默认 y): " "y" "APPEND_FRP")
else
log_warn "未找到 frpc 配置文件,跳过自动追加"
log_warn "请手动在 frpc 配置中添加以下规则:"
echo -e "${YELLOW}--- TOML 格式 ---${PLAIN}"
echo -e "[[proxies]]"
echo -e "name = \"huawei-dynamic-gateway\""
echo -e "type = \"tcp\""
echo -e "local_ip = \"127.0.0.1\""
echo -e "local_port = ${GATEWAY_PORT}"
echo -e "remote_port = ${REMOTE_PORT}"
fi
# ================= 安装 Python 依赖 =================
log_step "4/5" "部署 Python 运行环境..."
# 检查 python3
PYTHON_CMD=""
for cmd in python3 python3.11 python3.10 python3.9 python3.8; do
if command -v "$cmd" &>/dev/null; then
PYTHON_CMD="$cmd"
break
fi
done
if [ -z "$PYTHON_CMD" ]; then
log_warn "未找到 Python3,尝试自动安装..."
if command -v apt &>/dev/null; then
apt-get update -qq && apt-get install -y -qq python3 python3-pip
elif command -v yum &>/dev/null; then
yum install -y -q python3 python3-pip
elif command -v apk &>/dev/null; then
apk add --no-cache python3 py3-pip
else
log_error "无法自动安装 Python,请手动安装 python3 和 pip"
exit 1
fi
PYTHON_CMD="python3"
fi
# 检查 pip 并安装依赖
if ! $PYTHON_CMD -m pip --version &>/dev/null 2>&1; then
log_warn "pip 未安装,尝试安装..."
$PYTHON_CMD -m ensurepip --upgrade 2>/dev/null || {
if command -v apt &>/dev/null; then apt-get install -y -qq python3-pip; fi
}
fi
# 使用虚拟环境避免权限问题(可选)
USE_VENV=false
VENV_PATH="/opt/huawei-gateway/venv"
if [ "$IS_CONTAINER" = true ] || [ "$EUID" -eq 0 ]; then
USE_VENV_INPUT=$(read_or_default "是否使用虚拟环境安装 Python 依赖? (推荐, y/n, 默认 y): " "y" "USE_VENV")
[[ "$USE_VENV_INPUT" == "y" || "$USE_VENV_INPUT" == "Y" ]] && USE_VENV=true
fi
if [ "$USE_VENV" = true ]; then
mkdir -p /opt/huawei-gateway
$PYTHON_CMD -m venv "$VENV_PATH" 2>/dev/null || {
log_warn "无法创建虚拟环境,将使用系统 Python"
USE_VENV=false
}
fi
PIP_CMD="$PYTHON_CMD -m pip"
if [ "$USE_VENV" = true ]; then
PIP_CMD="$VENV_PATH/bin/pip"
PYTHON_CMD="$VENV_PATH/bin/python"
fi
# 安装依赖(使用国内镜像)
log_info "正在安装 Flask 和 requests..."
$PIP_CMD install --upgrade pip --quiet -i https://pypi.tuna.tsinghua.edu.cn/simple 2>/dev/null
$PIP_CMD install flask requests --quiet -i https://pypi.tuna.tsinghua.edu.cn/simple
# ================= 创建网关核心代码 =================
log_step "5/5" "生成网关代码并启动服务..."
mkdir -p /usr/local/bin /var/log /var/run
cat << 'PYEOF' > /usr/local/bin/huawei_gateway.py
#!/usr/bin/env python3
"""
华为云 Token 动态网关
- 6小时缓存机制
- 支持内存扫描自动刷新
- 401 自动重试
- 兼容生产环境 (Waitress/Gunicorn)
"""
import os
import re
import sys
import time
import logging
import threading
import traceback
from concurrent.futures import ThreadPoolExecutor, as_completed
from flask import Flask, request, Response
# 尝试导入 requests,失败则给出明确提示
try:
import requests
except ImportError:
print("错误:缺少 requests 模块。请运行: pip install requests")
sys.exit(1)
# ================= 配置 =================
CACHE_TTL = 19800 # 5.5 小时(安全线)
MAX_WORKERS = 8 # 内存扫描线程数
MAX_MEM_SEGMENT = 200 * 1024 * 1024 # 单段最大扫描 200MB
TOKEN_PATTERN = re.compile(b'Bearer ([A-Za-z0-9+/=_-]{100,})')
TARGET_HOST = 'tokenhub.developer.huaweicloud.com'
# ================= 日志 =================
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s [%(levelname)s] %(message)s',
handlers=[
logging.StreamHandler(sys.stdout)
]
)
logger = logging.getLogger('huawei-gateway')
# ================= 缓存 =================
class TokenCache:
def __init__(self):
self._token = None
self._expires_at = 0
self._lock = threading.RLock()
self._last_scan = 0
self._scan_interval = 60 # 扫描间隔最小 60 秒
def get(self):
with self._lock:
now = time.time()
if self._token and now < self._expires_at:
return self._token
return None
def set(self, token, ttl=CACHE_TTL):
with self._lock:
self._token = token
self._expires_at = time.time() + ttl
self._last_scan = time.time()
def is_scan_cooldown(self):
with self._lock:
return (time.time() - self._last_scan) < self._scan_interval
def clear(self):
with self._lock:
self._token = None
self._expires_at = 0
cache = TokenCache()
# ================= 内存扫描 =================
def scan_pid_mem(pid):
"""扫描单个进程的内存寻找 Token"""
maps_path = f'/proc/{pid}/maps'
mem_path = f'/proc/{pid}/mem'
if not os.path.exists(maps_path) or not os.path.exists(mem_path):
return None
try:
with open(maps_path, 'r') as f:
for line in f:
parts = line.split()
if len(parts) < 2:
continue
perms = parts[1]
if 'r' not in perms or 'w' not in perms: # 只扫描可读可写段(更精确)
continue
addrs = parts[0].split('-')
if len(addrs) != 2:
continue
start = int(addrs[0], 16)
end = int(addrs[1], 16)
size = end - start
# 跳过过大或过小的段
if size > MAX_MEM_SEGMENT or size < 1024:
continue
try:
with open(mem_path, 'rb') as mem:
mem.seek(start)
# 分段读取避免大内存占用
chunk_size = 64 * 1024
remaining = size
while remaining > 0:
to_read = min(chunk_size, remaining)
data = mem.read(to_read)
if not data:
break
for match in TOKEN_PATTERN.finditer(data):
token = match.group(1).decode('ascii', errors='replace')
# 验证 token 格式(华为云 token 通常是 JWT 格式)
if len(token) > 200 and token.count('.') >= 2:
return token
remaining -= len(data)
except (PermissionError, OSError, ValueError):
continue
except (PermissionError, OSError, ProcessLookupError):
pass
return None
def find_token_in_memory():
"""在所有进程中扫描 Token"""
if cache.is_scan_cooldown() and cache.get():
return cache.get()
try:
pids = [pid for pid in os.listdir('/proc') if pid.isdigit()]
except OSError:
logger.error("无法访问 /proc 目录")
return None
# 优先扫描常见进程(python, node, java 等可能持有 token 的进程)
priority_pids = []
other_pids = []
for pid in pids:
try:
exe_path = os.readlink(f'/proc/{pid}/exe')
if any(x in exe_path for x in ['python', 'node', 'java', 'chrome', 'electron']):
priority_pids.append(pid)
else:
other_pids.append(pid)
except (OSError, PermissionError):
other_pids.append(pid)
# 先扫描优先级进程
all_pids = priority_pids + other_pids
with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
futures = {executor.submit(scan_pid_mem, pid): pid for pid in all_pids}
for future in as_completed(futures):
try:
token = future.result(timeout=5)
if token:
cache.set(token)
logger.info(f"Token 已刷新 (来源 PID: {futures[future]})")
return token
except Exception:
continue
return cache.get() # 返回可能过期的缓存作为兜底
# ================= Flask 应用 =================
app = Flask(__name__)
@app.route('/health')
def health():
"""健康检查端点"""
token = cache.get()
return {
"status": "healthy",
"token_cached": token is not None,
"token_expires_in": max(0, cache._expires_at - time.time()) if hasattr(cache, '_expires_at') else 0
}, 200
@app.route('/v2/<path:subpath>', methods=['POST', 'GET', 'OPTIONS', 'PUT', 'DELETE'])
def proxy(subpath):
if request.method == 'OPTIONS':
return Response(status=200, headers={
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization'
})
real_token = find_token_in_memory()
if not real_token:
logger.error("未在内存中找到华为云 Token")
return {"error": "未在内存中找到华为云Token,请确保华为云相关应用正在运行"}, 500
# 构建请求头
headers = {}
for k, v in request.headers:
kl = k.lower()
if kl not in ('host', 'content-length', 'connection', 'accept-encoding'):
headers[k] = v
headers['Authorization'] = f'Bearer {real_token}'
headers['Host'] = TARGET_HOST
target_url = f'https://{TARGET_HOST}/v2/{subpath}'
try:
resp = requests.request(
method=request.method,
url=target_url,
headers=headers,
data=request.get_data(),
cookies=request.cookies,
allow_redirects=False,
timeout=60,
stream=False
)
# 401 兜底:Token 可能提前过期,强制刷新重试一次
if resp.status_code == 401:
logger.warning("收到 401,尝试强制刷新 Token 并重试...")
cache.clear()
new_token = find_token_in_memory()
if new_token and new_token != real_token:
headers['Authorization'] = f'Bearer {new_token}'
resp = requests.request(
method=request.method,
url=target_url,
headers=headers,
data=request.get_data(),
cookies=request.cookies,
allow_redirects=False,
timeout=60
)
# 构建响应
response_headers = []
for k, v in resp.headers.items():
if k.lower() not in ('transfer-encoding', 'content-encoding', 'content-length'):
response_headers.append((k, v))
return Response(
resp.content,
status=resp.status_code,
headers=response_headers
)
except requests.exceptions.Timeout:
logger.error("请求华为云 API 超时")
return {"error": "网关超时,请稍后重试"}, 504
except requests.exceptions.ConnectionError:
logger.error("无法连接到华为云 API")
return {"error": "无法连接到华为云服务"}, 502
except Exception as e:
logger.error(f"网关转发失败: {traceback.format_exc()}")
return {"error": f"网关转发失败: {str(e)}"}, 500
def main():
port = int(sys.argv[1]) if len(sys.argv) > 1 else 8080
host = sys.argv[2] if len(sys.argv) > 2 else '127.0.0.1'
# 尝试使用生产级 WSGI 服务器
try:
import waitress
logger.info(f"使用 Waitress 启动网关 ({host}:{port})")
waitress.serve(app, host=host, port=port, threads=16)
except ImportError:
try:
import gunicorn.app.wsgiapp
logger.info(f"使用 Gunicorn 启动网关 ({host}:{port})")
os.execlp('gunicorn', 'gunicorn', '-w', '4', '-b', f'{host}:{port}', '--access-logfile', '-', 'huawei_gateway:app')
except (ImportError, OSError):
logger.warning("未安装 Waitress/Gunicorn,使用 Flask 开发服务器(建议生产环境安装 waitress")
logger.info(f"启动网关 ({host}:{port})")
app.run(host=host, port=port, debug=False, threaded=True)
if __name__ == '__main__':
main()
PYEOF
chmod +x /usr/local/bin/huawei_gateway.py
# ================= 注册网关服务 =================
if has_systemd; then
cat << EOF > /etc/systemd/system/huawei-gateway.service
[Unit]
Description=Huawei Dynamic Gateway (6H Cache)
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
ExecStart=$PYTHON_CMD /usr/local/bin/huawei_gateway.py $GATEWAY_PORT
Restart=always
RestartSec=3
StartLimitInterval=60s
StartLimitBurst=3
StandardOutput=append:/var/log/huawei-gateway.log
StandardError=append:/var/log/huawei-gateway.log
[Install]
WantedBy=multi-user.target
EOF
fi
# 启动服务
safe_start_service "huawei-gateway" "$PYTHON_CMD /usr/local/bin/huawei_gateway.py $GATEWAY_PORT" "/etc/systemd/system/huawei-gateway.service"
# ================= 追加 frpc 规则 =================
if [[ "$APPEND_FRP" == "y" || "$APPEND_FRP" == "Y" ]] && [ -n "$FRPC_CONFIG" ] && [ -f "$FRPC_CONFIG" ]; then
if grep -q "huawei-dynamic-gateway" "$FRPC_CONFIG" 2>/dev/null; then
log_warn "frpc 配置中已存在 huawei-dynamic-gateway 规则,跳过追加"
else
# 备份原配置
cp "$FRPC_CONFIG" "${FRPC_CONFIG}.backup.$(date +%Y%m%d%H%M%S)"
if [ "$FRPC_TYPE" = "toml" ]; then
cat << EOF >> "$FRPC_CONFIG"
[[proxies]]
name = "huawei-dynamic-gateway"
type = "tcp"
local_ip = "127.0.0.1"
local_port = $GATEWAY_PORT
remote_port = $REMOTE_PORT
EOF
else
cat << EOF >> "$FRPC_CONFIG"
[huawei-dynamic-gateway]
type = tcp
local_ip = 127.0.0.1
local_port = $GATEWAY_PORT
remote_port = $REMOTE_PORT
EOF
fi
log_info "frpc 代理规则已追加到 $FRPC_CONFIG"
log_info "原配置已备份"
fi
# 重启 frpc
if has_systemd; then
if systemctl list-units --type=service 2>/dev/null | grep -q "frpc"; then
systemctl restart frpc 2>/dev/null && log_info "frpc 服务已重启"
fi
else
restart_service "frpc"
# 尝试直接启动 frpc
if command -v frpc &>/dev/null; then
nohup frpc -c "$FRPC_CONFIG" > /var/log/frpc.log 2>&1 &
log_info "frpc 已通过 nohup 启动"
fi
fi
fi
# ================= 部署总结 =================
echo -e "\n${BLUE}==================================================${PLAIN}"
echo -e "${GREEN} 🎉 6小时长效缓存网关部署完成 🎉 ${PLAIN}"
echo -e "${BLUE}==================================================${PLAIN}"
echo -e "1. 动态网关状态:$(get_service_status huawei-gateway)"
echo -e "2. 健康检查: http://127.0.0.1:${GATEWAY_PORT}/health"
echo -e "3. 您的本地一劳永逸调用地址:"
echo -e " - ${GREEN}API Base URL:${PLAIN} http://【你的公网frps_IP】:$REMOTE_PORT/v2"
echo -e " - ${GREEN}API Key:${PLAIN} sk-anything"
echo -e " - ${GREEN}Model:${PLAIN} glm-5.1"
if [ "$IS_CONTAINER" = true ]; then
echo -e "\n${YELLOW}[容器环境提示]${PLAIN}"
echo -e " - 服务通过 nohup 运行,日志位于 /var/log/huawei-gateway.log"
echo -e " - 如需停止服务: kill \$(cat /var/run/huawei-gateway.pid)"
echo -e " - 建议安装 waitress 提升性能: pip install waitress"
fi
echo -e "${BLUE}==================================================${PLAIN}\n"