From 9f1e293d4cdf5552eaecf04b4823e1bd254faeb6 Mon Sep 17 00:00:00 2001 From: Joywayer Date: Thu, 6 Aug 2026 17:02:15 +0800 Subject: [PATCH] =?UTF-8?q?feat(vps-xray):=20=E6=96=B0=E5=A2=9E=20--restar?= =?UTF-8?q?t=20=E8=BD=BB=E9=87=8F=E5=85=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 只改定时重启计划并立即生效,不重装 Xray、不重写配置、不重启服务, 与 --mode/--show/--redetect 互斥。 顺带修正非法参数以退出码 0 结束的问题。 --- vps-xray/deploy.sh | 88 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 2 deletions(-) diff --git a/vps-xray/deploy.sh b/vps-xray/deploy.sh index 9b966f2..ad70a60 100644 --- a/vps-xray/deploy.sh +++ b/vps-xray/deploy.sh @@ -31,8 +31,13 @@ usage() { echo " --show 只读取 .env 打印连接信息和分享链接,不改动任何服务" echo " --redetect 强制重新挑选 Reality 伪装目标(会改变 SNI," echo " 所有客户端链接都必须同步更新)" + echo " --restart [N] [HH:MM]" + echo " 只修改定时重启计划并立即生效。N=0 关闭。" + echo " 不重装 Xray、不重写配置、不重启服务," + echo " 现有 vless 链接完全不受影响。" + echo " 例: bash deploy.sh --restart 7 04:00" echo " -h, --help 显示帮助" - exit 0 + exit "${1:-0}" } # ===== 解析参数 ===== @@ -40,16 +45,40 @@ MODE="" MODE_EXPLICIT=0 SHOW_ONLY=0 REDETECT=0 +RESTART_ONLY=0 +RESTART_ARG_DAYS="" +RESTART_ARG_TIME="" while [[ $# -gt 0 ]]; do case $1 in --mode) MODE="${2:-}"; MODE_EXPLICIT=1; shift 2 ;; --show) SHOW_ONLY=1; shift ;; --redetect) REDETECT=1; shift ;; + --restart) + RESTART_ONLY=1 + shift + # 后面可跟 0~2 个位置参数,按形态判断,不会误吞后续选项 + if [[ "${1:-}" =~ ^[0-9]+$ ]]; then + RESTART_ARG_DAYS="$1" + shift + if [[ "${1:-}" =~ ^([01]?[0-9]|2[0-3]):[0-5][0-9]$ ]]; then + RESTART_ARG_TIME="$1" + shift + fi + fi + ;; -h|--help) usage ;; - *) error "未知参数: $1"; usage ;; + *) error "未知参数: $1"; usage 1 ;; esac done +# --restart 是「只改重启计划」的轻量入口,与会改动服务的选项互斥, +# 避免用户以为只调了 timer、实际却顺带重装了 Xray +if [ "$RESTART_ONLY" -eq 1 ] \ + && { [ "$MODE_EXPLICIT" -eq 1 ] || [ "$SHOW_ONLY" -eq 1 ] || [ "$REDETECT" -eq 1 ]; }; then + error "--restart 不能与 --mode / --show / --redetect 同时使用" + exit 1 +fi + # ===== 检查 root ===== # .env 权限为 600,读取它同样需要 root if [ "$(id -u)" -ne 0 ]; then @@ -246,6 +275,56 @@ configure_restart_timer() { warn "重启会切断所有活动连接;崩溃恢复本已由 Restart=always 覆盖,按需启用" } +# ===== --restart:只改重启计划 ===== +# 明确不做:装依赖、升级 Xray、生成密钥、选伪装目标、重写 config.json、 +# 改防火墙与 sysctl、重启 xray。因此 vless 链接与现有连接均不受影响。 +apply_restart_only() { + local env_file="$SCRIPT_DIR/.env" + + if [ ! -f "$env_file" ]; then + error "未找到 ${env_file},无法确认这是一台已部署的机器" + error "请先执行完整部署: bash deploy.sh" + exit 1 + fi + if ! systemctl cat xray >/dev/null 2>&1; then + error "未找到 xray.service,请先执行完整部署: bash deploy.sh" + exit 1 + fi + + # 命令行给了值就覆盖 .env 载入的值,没给则沿用 + if [ -n "$RESTART_ARG_DAYS" ]; then + XRAY_RESTART_EVERY_DAYS="$RESTART_ARG_DAYS" + fi + if [ -n "$RESTART_ARG_TIME" ]; then + XRAY_RESTART_TIME="$RESTART_ARG_TIME" + fi + resolve_restart_config || exit 1 + + # 只把命令行显式给过的字段落盘,没给的不动 .env + if [ -n "$RESTART_ARG_DAYS" ]; then + update_env_field "$env_file" XRAY_RESTART_EVERY_DAYS "$RESTART_EVERY_DAYS" + fi + if [ -n "$RESTART_ARG_TIME" ]; then + update_env_field "$env_file" XRAY_RESTART_TIME "$RESTART_TIME" + fi + + configure_restart_timer + + echo "" + echo "==========================================================" + if [ "$RESTART_EVERY_DAYS" -eq 0 ]; then + echo " 定时重启: 已关闭" + else + echo " 定时重启: 每 ${RESTART_EVERY_DAYS} 天 ${RESTART_TIME} (${RESTART_TZ})" + fi + echo " xray 服务未重启,vless 链接与现有连接均未受影响。" + echo "==========================================================" + if [ "$RESTART_EVERY_DAYS" -ne 0 ]; then + echo "" + systemctl list-timers xray-restart.timer --no-pager 2>/dev/null || true + fi +} + resolve_restart_config || exit 1 XRAY_PORT="${XRAY_PORT:-443}" @@ -1033,6 +1112,11 @@ main() { exit 0 fi + if [ "$RESTART_ONLY" -eq 1 ]; then + apply_restart_only + exit 0 + fi + echo "" log "部署模式: ${MODE}" [ "$MODE" = "reality" ] && log "VLESS-Reality(推荐,抗封锁)" || log "VLESS TCP(极速,无 TLS)"