修复容器环境三个关键bug:systemd误判、变量名冲突、启动验证
- has_systemd(): 改为检查 /proc/1/comm 是否为 systemd,避免容器中 systemctl --version 误判 - read_or_default(): 简化为两参数,去掉变量名间接引用避免冲突 - 新增 confirm_or_default(): 处理 y/n 确认,管道模式默认 true - safe_start_service(): systemd 启动失败自动回退到 nohup - safe_start_service(): 启动后 sleep 1 并验证进程存活,失败输出日志路径 - get_service_status(): unknown -> inactive(更准确的措辞) - 端口变量支持环境变量覆盖: GATEWAY_PORT/REMOTE_PORT
This commit is contained in:
+59
-40
@@ -13,55 +13,71 @@ log_warn() { echo -e "${YELLOW}[WARN]${PLAIN} $1"; }
|
|||||||
log_error() { echo -e "${RED}[ERROR]${PLAIN} $1"; }
|
log_error() { echo -e "${RED}[ERROR]${PLAIN} $1"; }
|
||||||
log_step() { echo -e "\n${BLUE}[${1}]${PLAIN} ${2}"; }
|
log_step() { echo -e "\n${BLUE}[${1}]${PLAIN} ${2}"; }
|
||||||
|
|
||||||
# 检测是否在管道中运行(stdin 不是 tty)
|
# 交互式读取或自动使用默认值(管道模式下静默使用默认值)
|
||||||
is_piped() {
|
|
||||||
[ ! -t 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
# 交互式读取或自动使用默认值
|
|
||||||
read_or_default() {
|
read_or_default() {
|
||||||
local prompt_msg="$1"
|
local prompt_msg="$1"
|
||||||
local default_value="$2"
|
local default_value="$2"
|
||||||
local var_name="$3"
|
|
||||||
|
|
||||||
if is_piped; then
|
if [ -t 0 ]; 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
|
read -p "$prompt_msg" input_val
|
||||||
echo "${input_val:-$default_value}"
|
echo "${input_val:-$default_value}"
|
||||||
|
else
|
||||||
|
echo "$default_value"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# 交互式确认(管道模式下默认返回 true)
|
||||||
|
confirm_or_default() {
|
||||||
|
local prompt_msg="$1"
|
||||||
|
local default="$2"
|
||||||
|
|
||||||
|
if [ -t 0 ]; then
|
||||||
|
read -p "$prompt_msg" answer
|
||||||
|
answer="${answer:-$default}"
|
||||||
|
[[ "$answer" == "y" || "$answer" == "Y" ]]
|
||||||
|
else
|
||||||
|
[[ "$default" == "y" || "$default" == "Y" ]]
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
# 检查是否有 systemd(pid=1 是 systemd 才算真正有 systemd)
|
||||||
has_systemd() {
|
has_systemd() {
|
||||||
[ -d /run/systemd/system ] || [ -d /var/run/systemd/system ] || systemctl --version &>/dev/null
|
[ -f /proc/1/comm ] && grep -qx "systemd" /proc/1/comm 2>/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
# 安全的进程启动(支持 systemd 和 nohup 两种模式)
|
# 安全的进程启动(支持 systemd 和 nohup 两种模式)
|
||||||
|
# 返回 0 表示启动成功
|
||||||
safe_start_service() {
|
safe_start_service() {
|
||||||
local name=$1
|
local name=$1
|
||||||
local cmd=$2
|
local cmd=$2
|
||||||
local service_file=$3
|
|
||||||
|
|
||||||
if has_systemd; then
|
if has_systemd; then
|
||||||
systemctl daemon-reload 2>/dev/null
|
systemctl daemon-reload 2>/dev/null
|
||||||
systemctl enable "$name" --now 2>/dev/null
|
if systemctl enable "$name" --now 2>/dev/null; then
|
||||||
log_info "$name 已通过 systemd 启动"
|
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
|
return 0
|
||||||
fi
|
fi
|
||||||
nohup $cmd > "/var/log/${name}.log" 2>&1 &
|
# systemd 启动失败,回退到 nohup
|
||||||
echo $! > "$pid_file"
|
log_warn "systemd 启动失败,回退到 nohup 模式"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 容器/无 systemd 环境:使用 nohup + 简单的 PID 文件管理
|
||||||
|
local pid_file="/var/run/${name}.pid"
|
||||||
|
local log_file="/var/log/${name}.log"
|
||||||
|
|
||||||
|
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 > "$log_file" 2>&1 &
|
||||||
|
echo $! > "$pid_file"
|
||||||
|
sleep 1
|
||||||
|
if kill -0 "$!" 2>/dev/null; then
|
||||||
log_info "$name 已通过 nohup 启动 (PID: $!)"
|
log_info "$name 已通过 nohup 启动 (PID: $!)"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
log_error "$name 启动失败,查看日志: $log_file"
|
||||||
|
return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,7 +85,7 @@ safe_start_service() {
|
|||||||
get_service_status() {
|
get_service_status() {
|
||||||
local name=$1
|
local name=$1
|
||||||
if has_systemd; then
|
if has_systemd; then
|
||||||
systemctl is-active "$name" 2>/dev/null || echo "unknown"
|
systemctl is-active "$name" 2>/dev/null || echo "inactive"
|
||||||
else
|
else
|
||||||
local pid_file="/var/run/${name}.pid"
|
local pid_file="/var/run/${name}.pid"
|
||||||
if [ -f "$pid_file" ] && kill -0 "$(cat "$pid_file")" 2>/dev/null; then
|
if [ -f "$pid_file" ] && kill -0 "$(cat "$pid_file")" 2>/dev/null; then
|
||||||
@@ -87,8 +103,10 @@ restart_service() {
|
|||||||
systemctl restart "$name" 2>/dev/null
|
systemctl restart "$name" 2>/dev/null
|
||||||
else
|
else
|
||||||
local pid_file="/var/run/${name}.pid"
|
local pid_file="/var/run/${name}.pid"
|
||||||
[ -f "$pid_file" ] && kill "$(cat "$pid_file")" 2>/dev/null
|
if [ -f "$pid_file" ]; then
|
||||||
sleep 1
|
kill "$(cat "$pid_file")" 2>/dev/null
|
||||||
|
sleep 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,9 +131,7 @@ fi
|
|||||||
log_step "1/5" "正在检测 frpc 环境..."
|
log_step "1/5" "正在检测 frpc 环境..."
|
||||||
if ! command -v frpc &>/dev/null && [ ! -f "/usr/local/bin/frpc" ] && [ ! -f "/usr/bin/frpc" ]; then
|
if ! command -v frpc &>/dev/null && [ ! -f "/usr/local/bin/frpc" ] && [ ! -f "/usr/bin/frpc" ]; then
|
||||||
log_warn "未检测到 frpc!"
|
log_warn "未检测到 frpc!"
|
||||||
INSTALL_FRP=$(read_or_default "是否需要为您自动下载并安装最新版 frpc (使用国内加速镜像)? (y/n, 默认 y): " "y" "INSTALL_FRP")
|
if confirm_or_default "是否需要为您自动下载并安装最新版 frpc (使用国内加速镜像)? (y/n, 默认 y): " "y"; then
|
||||||
|
|
||||||
if [[ "$INSTALL_FRP" == "y" || "$INSTALL_FRP" == "Y" ]]; then
|
|
||||||
ARCH=$(uname -m)
|
ARCH=$(uname -m)
|
||||||
case "$ARCH" in
|
case "$ARCH" in
|
||||||
x86_64) FRP_ARCH="amd64" ;;
|
x86_64) FRP_ARCH="amd64" ;;
|
||||||
@@ -201,8 +217,8 @@ fi
|
|||||||
# ================= 配置网关与映射端口 =================
|
# ================= 配置网关与映射端口 =================
|
||||||
log_step "2/5" "配置动态网关参数:"
|
log_step "2/5" "配置动态网关参数:"
|
||||||
|
|
||||||
GATEWAY_PORT=$(read_or_default "请输入 Python 动态网关的本地监听端口 (默认 8080): " "8080" "GATEWAY_PORT")
|
GATEWAY_PORT="${GATEWAY_PORT:-$(read_or_default "请输入 Python 动态网关的本地监听端口 (默认 8080): " "8080")}"
|
||||||
REMOTE_PORT=$(read_or_default "请输入你想在 frps 公网端暴露的端口 (默认 18000): " "18000" "REMOTE_PORT")
|
REMOTE_PORT="${REMOTE_PORT:-$(read_or_default "请输入你想在 frps 公网端暴露的端口 (默认 18000): " "18000")}"
|
||||||
|
|
||||||
# 端口有效性检查
|
# 端口有效性检查
|
||||||
if ! [[ "$GATEWAY_PORT" =~ ^[0-9]+$ ]] || [ "$GATEWAY_PORT" -lt 1 ] || [ "$GATEWAY_PORT" -gt 65535 ]; then
|
if ! [[ "$GATEWAY_PORT" =~ ^[0-9]+$ ]] || [ "$GATEWAY_PORT" -lt 1 ] || [ "$GATEWAY_PORT" -gt 65535 ]; then
|
||||||
@@ -240,7 +256,9 @@ fi
|
|||||||
APPEND_FRP="n"
|
APPEND_FRP="n"
|
||||||
if [ -n "$FRPC_CONFIG" ]; then
|
if [ -n "$FRPC_CONFIG" ]; then
|
||||||
log_info "识别到 frpc 配置: $FRPC_CONFIG (${FRPC_TYPE})"
|
log_info "识别到 frpc 配置: $FRPC_CONFIG (${FRPC_TYPE})"
|
||||||
APPEND_FRP=$(read_or_default "是否自动将华为云转发规则追加到该文件? (y/n, 默认 y): " "y" "APPEND_FRP")
|
if confirm_or_default "是否自动将华为云转发规则追加到该文件? (y/n, 默认 y): " "y"; then
|
||||||
|
APPEND_FRP="y"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
log_warn "未找到 frpc 配置文件,跳过自动追加"
|
log_warn "未找到 frpc 配置文件,跳过自动追加"
|
||||||
log_warn "请手动在 frpc 配置中添加以下规则:"
|
log_warn "请手动在 frpc 配置中添加以下规则:"
|
||||||
@@ -292,8 +310,9 @@ fi
|
|||||||
USE_VENV=false
|
USE_VENV=false
|
||||||
VENV_PATH="/opt/huawei-gateway/venv"
|
VENV_PATH="/opt/huawei-gateway/venv"
|
||||||
if [ "$IS_CONTAINER" = true ] || [ "$EUID" -eq 0 ]; then
|
if [ "$IS_CONTAINER" = true ] || [ "$EUID" -eq 0 ]; then
|
||||||
USE_VENV_INPUT=$(read_or_default "是否使用虚拟环境安装 Python 依赖? (推荐, y/n, 默认 y): " "y" "USE_VENV")
|
if confirm_or_default "是否使用虚拟环境安装 Python 依赖? (推荐, y/n, 默认 y): " "y"; then
|
||||||
[[ "$USE_VENV_INPUT" == "y" || "$USE_VENV_INPUT" == "Y" ]] && USE_VENV=true
|
USE_VENV=true
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$USE_VENV" = true ]; then
|
if [ "$USE_VENV" = true ]; then
|
||||||
@@ -641,7 +660,7 @@ EOF
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# 启动服务
|
# 启动服务
|
||||||
safe_start_service "huawei-gateway" "$PYTHON_CMD /usr/local/bin/huawei_gateway.py $GATEWAY_PORT" "/etc/systemd/system/huawei-gateway.service"
|
safe_start_service "huawei-gateway" "$PYTHON_CMD /usr/local/bin/huawei_gateway.py $GATEWAY_PORT"
|
||||||
|
|
||||||
# ================= 追加 frpc 规则 =================
|
# ================= 追加 frpc 规则 =================
|
||||||
if [[ "$APPEND_FRP" == "y" || "$APPEND_FRP" == "Y" ]] && [ -n "$FRPC_CONFIG" ] && [ -f "$FRPC_CONFIG" ]; then
|
if [[ "$APPEND_FRP" == "y" || "$APPEND_FRP" == "Y" ]] && [ -n "$FRPC_CONFIG" ] && [ -f "$FRPC_CONFIG" ]; then
|
||||||
|
|||||||
Reference in New Issue
Block a user