#!/bin/bash
#
# OpenClaw 升级脚本 (npm 全局安装)
# 适用于: 物理内存 < 4G + 云端 API 模型 (跳过 llama.cpp 编译)
# 用法:
#   sudo bash upgrade_openclaw.sh           # 正常升级
#   sudo bash upgrade_openclaw.sh --rollback 20260311  # 回滚到指定日期的备份
#
set -o pipefail

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# ---------- 权限检查 ----------
if [ "$EUID" -ne 0 ]; then
    echo -e "${RED}请使用 root 或 sudo 运行此脚本。${NC}"
    exit 1
fi

# ---------- 函数: 回滚 ----------
rollback() {
    local BACKUP_DATE="$1"
    local BACKUP_DIR="$HOME/.openclaw-backup-${BACKUP_DATE}"

    if [ ! -d "$BACKUP_DIR" ]; then
        echo -e "${RED}错误: 备份目录 $BACKUP_DIR 不存在。${NC}"
        exit 1
    fi

    echo -e "${YELLOW}>>> 回滚至备份: ${BACKUP_DATE}${NC}"
    openclaw gateway stop 2>/dev/null || true
    rm -rf "$HOME/.openclaw"
    cp -r "$BACKUP_DIR" "$HOME/.openclaw"
    echo -e "${GREEN}配置已恢复。${NC}"

    npm install -g openclaw@2026.2.24 --ignore-scripts
    cd /usr/lib/node_modules/openclaw || exit 1
    npm rebuild --ignore-scripts 2>/dev/null || true

    openclaw gateway start
    echo -e "${GREEN}回滚完成,已启动 openclaw@2026.2.24${NC}"
    exit 0
}

# ---------- 参数解析 ----------
if [ "$1" = "--rollback" ]; then
    if [ -z "$2" ]; then
        echo -e "${RED}用法: $0 --rollback YYYYMMDD${NC}"
        exit 1
    fi
    rollback "$2"
fi

# ========== 升级流程 ==========

echo -e "${GREEN}================================${NC}"
echo -e "${GREEN}  OpenClaw 升级脚本 (-)${NC}"
echo -e "${GREEN}================================${NC}"

# 1. 检查安装方式 (必须是 npm)
OPENCLAW_BIN=$(which openclaw 2>/dev/null)
if [ -z "$OPENCLAW_BIN" ]; then
    echo -e "${RED}未找到 openclaw 命令,请确认已安装。${NC}"
    exit 1
fi
if [[ "$OPENCLAW_BIN" != *"/usr/local/bin/openclaw"* && "$OPENCLAW_BIN" != *"/usr/bin/openclaw"* && "$OPENCLAW_BIN" != *"/bin/openclaw"* ]]; then
    echo -e "${YELLOW}检测到非标准路径: ${OPENCLAW_BIN}${NC}"
    echo -e "${YELLOW}可能为 Docker 安装,本脚本仅适用于 npm 全局安装。${NC}"
    echo -e "${YELLOW}请使用 docker pull 升级。退出。${NC}"
    exit 1
fi
echo -e "${GREEN}✓ 检测到 npm 全局安装${NC}"

# 2. 检查内存与 Swap (仅内存 < 4G 时要求 Swap >= 2G)
TOTAL_MEM_KB=$(awk '/MemTotal/{print $2}' /proc/meminfo)
TOTAL_MEM_MB=$((TOTAL_MEM_KB / 1024))
SWAP_TOTAL_KB=$(awk '/SwapTotal/{print $2}' /proc/meminfo)
SWAP_TOTAL_MB=$((SWAP_TOTAL_KB / 1024))

if [ "$TOTAL_MEM_MB" -lt 4000 ]; then
    echo -e "${YELLOW}物理内存: ${TOTAL_MEM_MB}MB (<4G),检查 Swap...${NC}"
    if [ "$SWAP_TOTAL_MB" -lt 2000 ]; then
        echo -e "${RED}Swap 总计: ${SWAP_TOTAL_MB}MB (<2G),不满足最低要求。${NC}"
        echo -e "${YELLOW}请先创建至少 2G 的 Swap 文件,例如:${NC}"
        echo    "  sudo dd if=/dev/zero of=/swapfile bs=1M count=2048"
        echo    "  sudo chmod 600 /swapfile"
        echo    "  sudo mkswap /swapfile"
        echo    "  sudo swapon /swapfile"
        echo    "  并将 /swapfile 添加到 /etc/fstab 以持久化。"
        exit 1
    else
        echo -e "${GREEN}✓ Swap 满足要求 (${SWAP_TOTAL_MB}MB)${NC}"
    fi
else
    echo -e "${GREEN}✓ 物理内存充足 (${TOTAL_MEM_MB}MB)${NC}"
fi

# 3. 停止 Gateway 服务
echo -e "${YELLOW}>>> 停止 openclaw gateway...${NC}"
openclaw gateway stop 2>/dev/null || echo -e "${YELLOW}Gateway 可能未在运行,继续。${NC}"

# 4. 备份配置
BACKUP_DIR="$HOME/.openclaw-backup-$(date +%Y%m%d-%H%M%S)"
echo -e "${YELLOW}>>> 备份配置到 ${BACKUP_DIR}${NC}"
cp -r "$HOME/.openclaw" "$BACKUP_DIR"
echo -e "${GREEN}✓ 备份完成${NC}"

# 5. 配置 Git 使用 HTTPS (避免 SSH 权限问题)
echo -e "${YELLOW}>>> 配置 Git 自动使用 HTTPS 替代 SSH...${NC}"
git config --global url."https://github.com/".insteadOf ssh://git@github.com/
git config --global url."https://github.com/".insteadOf git@github.com:
echo -e "${GREEN}✓ Git 配置完成${NC}"

# 6. 清理旧的 node_modules
echo -e "${YELLOW}>>> 清理残留文件...${NC}"
rm -rf /usr/lib/node_modules/openclaw
rm -rf /usr/lib/node_modules/.openclaw-*
echo -e "${GREEN}✓ 清理完成${NC}"

# 7. 安装新版本 (跳过编译)
echo -e "${YELLOW}>>> 安装 openclaw@latest (跳过编译)...${NC}"
npm install -g openclaw@2026.4.15 --ignore-scripts
if [ $? -ne 0 ]; then
    echo -e "${RED}安装失败,请检查错误信息。${NC}"
    echo -e "${YELLOW}你可以使用以下命令回滚: sudo bash $0 --rollback $(basename $BACKUP_DIR | sed 's/.*-//')${NC}"
    exit 1
fi
echo -e "${GREEN}✓ 安装完成${NC}"

# 8. 手动 rebuild (安全操作)
if [ -d "/usr/lib/node_modules/openclaw" ]; then
    cd /usr/lib/node_modules/openclaw || exit 1
    npm rebuild --ignore-scripts 2>/dev/null || true
    echo -e "${GREEN}✓  rebuild 完成${NC}"
else
    echo -e "${RED}错误: 安装目录不存在。${NC}"
    exit 1
fi

# 9. 验证版本
echo -e "${YELLOW}>>> 验证安装版本...${NC}"
INSTALLED_VERSION=$(npm list -g openclaw 2>/dev/null | grep openclaw@ | head -1 | awk -F@ '{print $2}')
PACKAGE_VERSION=$(grep '"version"' /usr/lib/node_modules/openclaw/package.json | head -1 | awk -F'"' '{print $4}')
echo "  npm list 版本: ${INSTALLED_VERSION}"
echo "  package.json 版本: ${PACKAGE_VERSION}"
echo -e "${YELLOW}注意: openclaw --version 可能显示旧版本 (build-info 未更新),不影响实际使用。${NC}"

# 10. 启动服务
echo -e "${YELLOW}>>> 启动 openclaw gateway...${NC}"
openclaw gateway start
sleep 2

# 11. 检查进程
if ps aux | grep -v grep | grep openclaw-gateway > /dev/null; then
    echo -e "${GREEN}✓ openclaw-gateway 进程运行中${NC}"
else
    echo -e "${RED}× 未检测到 gateway 进程,请手动检查。${NC}"
fi

# 12. 完成提示
echo -e "${GREEN}================================${NC}"
echo -e "${GREEN}  升级流程完成!${NC}"
echo -e "${GREEN}  当前备份: ${BACKUP_DIR}${NC}"
echo -e "${GREEN}================================${NC}"
echo -e "${YELLOW}如遇严重问题,使用以下命令回滚:${NC}"
echo -e "  sudo bash $0 --rollback $(basename $BACKUP_DIR | grep -oP '\d{8}-\d{6}$')"

exit 0

脚本关键点

  • 强制 root 权限:所有文件操作和全局安装都需要。

  • 内存/Swap 检查:物理内存 < 4G 时强制要求 Swap ≥ 2G,否则退出并提示创建 Swap 的命令。

  • 安装方式验证:只允许 npm 全局安装的路径,避免误操作 Docker 环境。

  • --ignore-scripts:跳过 node-llama-cpp 的编译,防止低内存服务器 OOM。

  • 备份与回滚:自动备份 ~/.openclaw,并提供 --rollback 选项一键恢复。

  • 版本显示说明:提醒 openclaw --version 可能不准,以 package.json 为准。

运行情况如下:

本脚本基于OpenClaw 升级指南:从 2026.2.24 到 2026.3.8 全记录_openlaw系统升级-CSDN博客

的步骤编写,安装版本为4.15,要安装其他版本的可以自行@修改字段

Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐