diff --git a/clashctl b/clashctl index 2c49da9..68a7a70 100755 --- a/clashctl +++ b/clashctl @@ -286,8 +286,28 @@ cmd_stop() { esac } +safe_regenerate_config() { + local config_file="$PROJECT_DIR/runtime/config.yaml" + + echo "[INFO] 正在重新生成配置 ..." + if bash "$PROJECT_DIR/scripts/generate_config.sh"; then + return 0 + fi + + echo "[WARN] 配置重新生成失败,可能是订阅不可用或网络异常" + + if [ -s "$config_file" ]; then + echo "[WARN] 检测到已有可用配置,继续沿用当前配置" + return 2 + fi + + echo "[ERROR] 未找到可用的本地配置,无法继续" + return 1 +} + cmd_update() { local branch remote_name dirty pull_ok=1 + local regen_result=0 if ! has_git_repo; then err "当前目录不是 Git 仓库: $PROJECT_DIR" @@ -302,7 +322,7 @@ cmd_update() { remote_name="origin" - # 保护本地 .env(如果你已经把 .env 忽略掉,这段也保留,兜底更稳) + # 保护本地 .env if [ -f "$PROJECT_DIR/.env" ]; then cp -f "$PROJECT_DIR/.env" "$PROJECT_DIR/.env.bak" 2>/dev/null || true fi @@ -340,35 +360,34 @@ cmd_update() { mv -f "$PROJECT_DIR/.env.bak" "$PROJECT_DIR/.env" 2>/dev/null || true fi - # 修复脚本权限,避免 203/EXEC echo "[INFO] 修复执行权限中..." + chmod +x "$PROJECT_DIR"/clashctl 2>/dev/null || true chmod +x "$PROJECT_DIR"/scripts/*.sh 2>/dev/null || true chmod +x "$PROJECT_DIR"/bin/* 2>/dev/null || true sed -i 's/\r$//' "$PROJECT_DIR"/scripts/*.sh 2>/dev/null || true - # 先停服务,避免 generate 时误判端口占用导致漂移 - echo "[INFO] 停止服务(准备重新生成配置)..." - if has_systemd; then - systemctl stop clash-for-linux.service 2>/dev/null || true - sleep 1 + safe_regenerate_config + regen_result=$? + + if [ "$regen_result" -eq 1 ]; then + err "配置生成失败,且不存在可用旧配置" + exit 1 fi - echo "[INFO] 生成配置中..." - if ! bash "$PROJECT_DIR/scripts/generate_config.sh"; then - err "配置生成失败" - exit 1 - fi - - echo "[INFO] 启动服务中..." + echo "[INFO] 正在重启服务 ..." if has_systemd; then - if ! systemctl start clash-for-linux.service; then - err "systemd 启动失败" + if ! systemctl restart clash-for-linux.service; then + err "systemd 重启失败" exit 1 fi echo "[INFO] 等待服务就绪..." if wait_for_systemd_active; then - ok "更新完成" + if [ "$regen_result" -eq 2 ]; then + ok "代码已更新,当前继续使用旧配置运行" + else + ok "更新完成" + fi cmd_status return 0 fi @@ -382,7 +401,11 @@ cmd_update() { exit 1 fi - ok "更新完成" + if [ "$regen_result" -eq 2 ]; then + ok "代码已更新,当前继续使用旧配置运行" + else + ok "更新完成" + fi cmd_status fi } @@ -390,6 +413,7 @@ cmd_update() { cmd_update_force() { local branch remote_name local env_file backup_file + local regen_result=0 if ! has_git_repo; then err "当前目录不是 Git 仓库: $PROJECT_DIR" @@ -429,9 +453,17 @@ cmd_update_force() { restore_local_env_overrides "$env_file" "$backup_file" fi - echo "[INFO] 正在重新生成配置 ..." - if ! bash "$PROJECT_DIR/scripts/generate_config.sh"; then - err "配置生成失败" + echo "[INFO] 修复执行权限中..." + chmod +x "$PROJECT_DIR"/clashctl 2>/dev/null || true + chmod +x "$PROJECT_DIR"/scripts/*.sh 2>/dev/null || true + chmod +x "$PROJECT_DIR"/bin/* 2>/dev/null || true + sed -i 's/\r$//' "$PROJECT_DIR"/scripts/*.sh 2>/dev/null || true + + safe_regenerate_config + regen_result=$? + + if [ "$regen_result" -eq 1 ]; then + err "配置生成失败,且不存在可用旧配置" exit 1 fi @@ -448,7 +480,11 @@ cmd_update_force() { } fi - ok "强制更新完成" + if [ "$regen_result" -eq 2 ]; then + ok "强制更新完成,当前继续使用旧配置运行" + else + ok "强制更新完成" + fi cmd_status }