niuma / start-openclaw.sh
shuiseliuli's picture
Update start-openclaw.sh
4dce253 verified
Raw
History Blame Contribute Delete
5.02 kB
#!/bin/bash
set -ex
# ==========================================
# 1. 环境初始化与核心工具定义
# ==========================================
mkdir -p /root/.openclaw/
BACKUP_CMD="python3 /app/sync.py backup"
# 定义带锁的备份函数
safe_backup() {
echo "[Backup] Attempting to acquire lock..."
flock -n /tmp/backup.lock -c "$BACKUP_CMD" || echo "[Backup] Lock busy. Skipped."
}
# ==========================================
# 2. 状态恢复与智能配置映射 (纯决策层)
# ==========================================
CONFIG_FILE="/root/.openclaw/openclaw.json"
MARKER_FILE="/root/.openclaw/.version_marker"
# 获取新版本号并拉取云端旧数据
CURRENT_VERSION=$(openclaw --version 2>/dev/null || echo "unknown")
# ================= 新增:物理核销本地缓存防线 =================
echo "[Pre-Restore] Clearing local huggingface cache to prevent stale data..."
rm -rf /root/.cache/huggingface/hub/* 2>/dev/null || true
rm -rf /tmp/*.tar.gz 2>/dev/null || true
# ==========================================================
python3 /app/sync.py restore || echo "[Restore] No backup found or failed."
RESTORED_VERSION=$(cat "$MARKER_FILE" 2>/dev/null || echo "none")
# 决策逻辑
if [ ! -s "$CONFIG_FILE" ]; then
echo "[Init] No config found. Applying fresh template..."
envsubst < /app/openclaw.json > "$CONFIG_FILE"
echo "$CURRENT_VERSION" > "$MARKER_FILE"
elif [ "$FORCE_OVERWRITE" = "true" ]; then
echo "[Config] FORCE_OVERWRITE triggered! Resetting to template..."
envsubst < /app/openclaw.json > "$CONFIG_FILE"
echo "$CURRENT_VERSION" > "$MARKER_FILE"
elif [ "$CURRENT_VERSION" != "$RESTORED_VERSION" ] && [ "$CURRENT_VERSION" != "unknown" ]; then
echo "[Upgrade] Upgrading from $RESTORED_VERSION to $CURRENT_VERSION."
echo "$CURRENT_VERSION" > "$MARKER_FILE"
else
echo "[Start] Version matches ($CURRENT_VERSION). Normal boot."
fi
# ==========================================
# 3. 预检、修复与统一固化 (执行层)
# ==========================================
# 清理浏览器残留缓存
rm -rf /root/.openclaw/browser/*/user-data/Singleton* /tmp/org.chromium.Chromium.* 2>/dev/null || true
# 统一交给 doctor 检查和修复
echo "[Doctor] Checking and fixing data structures..."
openclaw doctor --fix
# 只有在发生版本升级、强制重置或全新安装时,才在开机触发基础备份
if [ "$CURRENT_VERSION" != "$RESTORED_VERSION" ] || [ "$FORCE_OVERWRITE" = "true" ] || [ ! -s "$CONFIG_FILE" ]; then
echo "[Init/Upgrade] Performing baseline backup..."
safe_backup
fi
# ==========================================
# 4. 主进程启动与优雅关闭 (Graceful Shutdown)
# ==========================================
echo "[Main] Starting OpenClaw Gateway..."
# 真正启动网关的核心命令!
openclaw gateway run --port $PORT &
MAIN_PID=$!
# 关机保护逻辑
shutdown_handler() {
echo "[Shutdown] Caught termination signal! Forwarding SIGTERM to OpenClaw (PID $MAIN_PID)..."
kill -TERM $MAIN_PID 2>/dev/null || true
echo "[Shutdown] Waiting for OpenClaw to safely flush databases..."
wait $MAIN_PID || true
echo "[Shutdown] OpenClaw exited safely. Performing final monolithic backup..."
safe_backup
echo "[Shutdown] Data secured. Goodbye."
exit 0
}
# 捕获系统关机信号
trap shutdown_handler SIGTERM SIGINT
# ==========================================
# 5. 后台安全巡航备份 & 飞书指令监听器
# ==========================================
(
# 记录上一次定时备份的时间戳
LAST_BACKUP_TIME=$(date +%s)
BACKUP_INTERVAL=10800 # 3小时 = 10800秒
while kill -0 $MAIN_PID 2>/dev/null; do
sleep 5 # 每 5 秒轮询一次,极低性能损耗,但能实现飞书指令的“秒回”
CURRENT_TIME=$(date +%s)
# 触发条件 1:飞书旁路标记文件被创建
if [ -f "/tmp/trigger_backup" ]; then
echo "[巡航守护] Detected manual backup trigger from Feishu!"
rm -f "/tmp/trigger_backup" # 消费掉标记
safe_backup
LAST_BACKUP_TIME=$CURRENT_TIME # 重置计时器,避免刚手动备份完立马又触发自动备份
fi
# 触发条件 2:距离上次备份超过 3 小时
if [ $((CURRENT_TIME - LAST_BACKUP_TIME)) -ge $BACKUP_INTERVAL ]; then
echo "[巡航守护] 3 hours passed. Executing scheduled backup..."
safe_backup
LAST_BACKUP_TIME=$CURRENT_TIME # 重置计时器
fi
done
) &
LOOP_PID=$!
# ==========================================
# 6. 主进程阻塞
# ==========================================
# 脚本停在这里,维持容器长亮
wait $MAIN_PID
# 如果 OpenClaw 异常崩溃(非系统关机),杀掉巡航脚本,做最后一次抢救备份
echo "[Main] Gateway process exited unexpectedly. Attempting final rescue sync..."
kill $LOOP_PID 2>/dev/null || true
safe_backup