| #!/bin/bash |
| set -euo pipefail |
| echo "===== OpenClaw 启动脚本 v2.3 (简化版) =====" |
| echo "启动时间: $(date)" |
|
|
| echo "" |
| echo "=== 1. 初始化环境与目录 ===" |
| mkdir -p /root/.openclaw/{agents/main/sessions,credentials,sessions,skills} |
| echo "目录结构创建完成。" |
|
|
| echo "" |
| echo "=== 2. 从备份恢复数据 ===" |
| if python3 /app/sync.py restore; then |
| echo "✓ 数据恢复完成。" |
| else |
| echo "⚠️ 数据恢复失败,继续启动。" >&2 |
| fi |
|
|
| echo "" |
| echo "=== 3. 检查与安装技能 ===" |
| SKILLS=("openclaw-tavily-search") |
| INSTALLED_SKILLS=() |
|
|
| for skill in "${SKILLS[@]}"; do |
| echo "处理技能: $skill" |
| is_installed=false |
| |
| |
| if clawhub list 2>/dev/null | grep -q "$skill"; then |
| echo " ✓ 已安装" |
| is_installed=true |
| |
| elif [ -d "/app/skills/$skill" ] || [ -d "/root/.openclaw/skills/$skill" ]; then |
| echo " ✓ 目录已存在" |
| is_installed=true |
| |
| else |
| echo " 🔧 尝试安装..." |
| if clawhub install "$skill"; then |
| echo " ✓ 安装成功" |
| is_installed=true |
| else |
| echo " ⚠️ 安装失败" >&2 |
| fi |
| fi |
| |
| [ "$is_installed" = true ] && INSTALLED_SKILLS+=("$skill") |
| done |
|
|
|
|
| echo "" |
| echo "=== 4. 配置 API 地址与生成主配置 ===" |
| |
| CLEAN_BASE="${OPENAI_API_BASE%/}" |
| CLEAN_BASE="${CLEAN_BASE%/chat/completions}" |
| CLEAN_BASE="${CLEAN_BASE%/v1}" |
| CLEAN_BASE="${CLEAN_BASE}/v1" |
| echo "API 地址: $CLEAN_BASE" |
|
|
| |
| cat > /root/.openclaw/openclaw.json <<EOF |
| { |
| "models": { |
| "providers": { |
| "nvidia": { |
| "baseUrl": "$CLEAN_BASE", |
| "apiKey": "$OPENAI_API_KEY", |
| "api": "openai-completions", |
| "models": [ |
| { "id": "$MODEL", "name": "$MODEL", "contextWindow": 128000 } |
| ] |
| } |
| } |
| }, |
| "agents": { |
| "defaults": { |
| "model": { "primary": "nvidia/$MODEL" } |
| } |
| }, |
| "commands": { |
| "restart": true |
| }, |
| "gateway": { |
| "mode": "local", |
| "bind": "lan", |
| "port": $PORT, |
| "trustedProxies": ["127.0.0.1/8", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"], |
| "auth": { |
| "mode": "token", |
| "token": "$OPENCLAW_GATEWAY_PASSWORD" |
| }, |
| "controlUi": { |
| "allowedOrigins": ["*"], |
| "dangerouslyAllowHostHeaderOriginFallback": true, |
| "allowInsecureAuth": true, |
| "dangerouslyDisableDeviceAuth": true |
| } |
| }, |
| "plugins": { |
| "allow": ["openclaw-weixin"], |
| "entries": { |
| "openclaw-weixin": { |
| "enabled": true |
| } |
| } |
| }, |
| } |
| EOF |
| echo "配置生成完成" |
|
|
| echo "" |
| echo "=== 5. 设置权限与技能链接 ===" |
| chmod 700 /root/.openclaw |
| chmod 600 /root/.openclaw/openclaw.json |
| chmod 700 /root/.openclaw/{agents,credentials,sessions} |
| chmod 750 /root/.openclaw/skills |
|
|
| |
| for skill in "${INSTALLED_SKILLS[@]}"; do |
| for dir in "/app/skills/$skill" "/skills/$skill" "/root/.openclaw/skills/$skill"; do |
| if [ -d "$dir" ]; then |
| ln -sfn "$dir" "/root/.openclaw/skills/$(basename "$skill")" |
| echo "✓ 链接创建: $skill" |
| break |
| fi |
| done |
| done |
|
|
| echo "" |
| echo "=== 6. 运行启动前检查 ===" |
| if command -v openclaw &>/dev/null; then |
| openclaw doctor --fix 2>&1 | tee /tmp/openclaw-doctor-startup.log |
| echo "--- 已安装技能列表 ---" |
| openclaw skills list 2>&1 || true |
| else |
| echo "⚠️ openclaw 命令未找到" >&2 |
| fi |
|
|
| npm install -g @tencent-weixin/openclaw-weixin |
| openclaw plugins install "@tencent-weixin/openclaw-weixin" |
| openclaw channels login --channel openclaw-weixin |
|
|
| echo "" |
| echo "=== 7. 环境摘要 ===" |
| echo "端口: $PORT | 模型: $MODEL" |
| echo "API: ${CLEAN_BASE%/v1} (v1)" |
| echo "令牌: ${OPENCLAW_GATEWAY_PASSWORD:0:3}***" |
| echo "Tavily: ${TAVILY_API_KEY:0:5}***" |
|
|
| echo "" |
| echo "=== 8. 启动后台任务与主服务 ===" |
| |
| ( |
| while true; do |
| sleep 3600 |
| python3 /app/sync.py backup && echo "[$(date)] 备份完成" || echo "[$(date)] 备份失败" >&2 |
| done |
| ) & |
|
|
| echo "" |
| echo "======================================" |
| echo "启动 OpenClaw 网关..." |
| echo "======================================" |
| echo "" |
| exec openclaw gateway run --port "$PORT" |