概述
2026-07-17 上午发现 OpenClaw 无法使用,表现为
openclaw gateway restart返回 command not found。经过系统性排查(系统日志、shell 历史、包管理日志、节点进程日志),定位到根因:WSL 关机重启后,nvm 未自动激活正确的 Node.js 版本,导致 npm 全局安装的 openclaw 命令不在 PATH 中,而非真正的卸载。
排查背景
- Host:MS-Zephyrus16 (WSL2, Ubuntu 24.04.4 LTS)
- 用户:montarius
- OpenClaw 版本:v2026.7.1
- Node.js 版本:v22.23.1 (nvm 管理)
- Shell:zsh (oh-my-zsh) + bash
- 系统架构:WSL2 子系统中运行,使用
systemctl --user管理服务
📋 目录
排查目标与思路
目标
用户反馈:“帮我查一下昨天发生了什么,导致安装的 openclaw 被卸载”
当天上午执行 openclaw gateway restart 返回 command not found,用户据此推断 openclaw 被意外卸载。排查目标:确认是否真的发生了卸载,并定位根因。
排查思路
作为安全开发工程师,排查遵循系统取证分析标准流程:
┌─────────────────────────────────────────────────────┐
│ Step 1: 确认当前状态 │
│ - openclaw 命令是否存在? │
│ - npm 全局包是否还在? │
│ - gateway 进程是否运行? │
├─────────────────────────────────────────────────────┤
│ Step 2: 查看系统日志 (journalctl) │
│ - 节点进程是否异常退出? │
│ - 有无信号终止 (SIGTERM/SIGKILL)? │
│ - 有无 OOM Killer 事件? │
├─────────────────────────────────────────────────────┤
│ Step 3: 分析 Shell 历史记录 │
│ - 用户是否手动执行了 uninstall 命令? │
│ - 确切的操作时间点 │
├─────────────────────────────────────────────────────┤
│ Step 4: 检查包管理器日志 │
│ - dpkg/apt 日志中有无删除记录? │
├─────────────────────────────────────────────────────┤
│ Step 5: 分析身份认证日志 (auth.log) │
│ - sudo 执行记录,是否有 root 权限操作? │
├─────────────────────────────────────────────────────┤
│ Step 6: 交叉验证进程生命周期 │
│ - 节点进程 PID 生命周期 │
│ - 系统启动/关闭时间 │
└─────────────────────────────────────────────────────┘排查原则:任何非预期的卸载通常会在系统层面留下痕迹。逐层排除才能定位根因,不能仅凭一个
command not found就判断为卸载。
排查步骤详解
Step 1:确认当前状态
用户最初报告时,先确认 openclaw 的实际情况——是真卸载了还是只是 PATH 问题。
执行命令
# 1. 检查命令是否存在
which openclaw
# 预期:返回路径,如 /home/montarius/.nvm/versions/node/v22.23.1/bin/openclaw
# 实际:which: no openclaw in (...)
# 2. 检查 npm 全局包是否还在
npm list -g openclaw
# 输出:
# /home/montarius/.nvm/versions/node/v22.23.1/lib
# └── openclaw@2026.7.1
# 3. 检查 nvm 状态
nvm --version # 0.40.5
nvm list # 查看已安装的 Node 版本
nvm ls # 同上,查看当前激活版本输出及解读
$ which openclaw
which: no openclaw in (/usr/local/bin:/usr/bin:/bin)
$ npm list -g openclaw
/home/montarius/.nvm/versions/node/v22.23.1/lib
└── openclaw@2026.7.1关键发现:which openclaw 找不到,但 npm list -g openclaw 显示包仍然存在。这是一个矛盾的信号——包没有被卸载,只是命令不在 PATH 中。
Step 2:分析系统日志 (journalctl)
使用 journalctl 查看 systemd 日志中的 Node.js 进程活动,确定 gateway 进程在 7/16 是否正常运行,以及退出方式。
2.1 查看 7/16 全天的节点进程日志
# 查看 2026-07-16 全天日志中 openclaw 相关(PID 98829)
journalctl --since "2026-07-16 00:00:00" --until "2026-07-16 23:59:59" \
--no-pager | grep "node\[98829\]" | less输出示例(全天共 1142 条日志):
Jul 16 00:05:36 MS-Zephyrus16 node[98829]: 2026-07-16T00:05:36.521+08:00 [agents/tool-policy] tool policy removed 5 tool(s) via tools.profile (coding): agents_list, gateway, message, nodes, tts
Jul 16 00:05:36 MS-Zephyrus16 node[98829]: 2026-07-16T00:05:36.643+08:00 [provider-transport-fetch] [model-fetch] start provider=custom-claudecode-internal-geelib-360-cn api=anthropic-messages model=claude-sonnet-4-6 method=POST
Jul 16 00:05:36 MS-Zephyrus16 node[98829]: 2026-07-16T00:05:36.721+08:00 [provider-transport-fetch] [model-fetch] response provider=custom-claudecode-internal-geelib-360-cn api=anthropic-messages model=claude-sonnet-4-6 status=200 elapsedMs=75
Jul 16 00:05:40 MS-Zephyrus16 node[98829]: 2026-07-16T00:05:40.336+08:00 [tools] read failed: ENOENT: no such file or directory, access '/home/montarius/.openclaw/workspace/memory/task-queue.json'
...
Jul 16 09:00:10 MS-Zephyrus16 node[98829]: 2026-07-16T09:00:10.444+08:00 [agents/tool-policy] tool policy removed 5 tool(s) via tools.profile (coding): agents_list, gateway, message, nodes, tts
Jul 16 09:00:11 MS-Zephyrus16 node[98829]: 2026-07-16T09:00:11.095+08:00 [provider-transport-fetch] [model-fetch] response provider=... status=200 elapsedMs=102
...
Jul 16 22:19:49 MS-Zephyrus16 node[98829]: 2026-07-16T22:19:49.359+08:00 [memory] sync failed (session-start): Error: No API key found for provider "openai"解读:
- PID 98829 在 7/16 全天都有日志输出(活跃),进程持续运行
- 内容主要是
tool policy变更、model-fetch请求/响应、tools read failed(task-queue.json 不存在属于正常现象) - 有一个已知的
memory sync failed(OpenAI key 缺失),但这是已知问题,不影响 gateway 正常运行 - 其中 11:07 和 11:14 有
LLM idle timeout,说明模型有超时,但进程未崩溃
2.2 检查进程退出方式
# 查看 WSL 关机时刻的日志
journalctl --since "2026-07-17 00:44:00" --until "2026-07-17 00:46:00" \
--no-pager输出:
Jul 17 00:44:25 MS-Zephyrus16 systemd-resolved[161]: Clock change detected. Flushing caches.
Jul 17 00:44:43 MS-Zephyrus16 node[98829]: [ws] webchat disconnected code=1006 reason=n/a
Jul 17 00:44:53 MS-Zephyrus16 node[98829]: [skills] watcher error: EFAULT: bad address
Jul 17 00:44:53 MS-Zephyrus16 node[98829]: [skills] watcher error: EIO: i/o error
Jul 17 00:45:01 MS-Zephyrus16 unknown: WSL Relay ERROR: ReceiveMessage:253: ExpectedMessage LxInitMessageExitStatus, but socket Control was closed
Jul 17 00:45:05 MS-Zephyrus16 systemd-logind[179]: The system will power off now!
Jul 17 00:45:05 MS-Zephyrus16 systemd[1]: Stopping session-2.scope...
Jul 17 00:45:05 MS-Zephyrus16 systemd[233]: Stopping openclaw-gateway.service...
Jul 17 00:45:05 MS-Zephyrus16 node[98829]: [gateway] signal SIGTERM received
Jul 17 00:45:05 MS-Zephyrus16 node[98829]: [gateway] received SIGTERM; shutting down
Jul 17 00:45:07 MS-Zephyrus16 systemd[233]: Stopped openclaw-gateway.service - OpenClaw Gateway (v2026.7.1).解读:
webchat disconnected code=1006— WebSocket 在关机前先断开watcher error— WSL 关机过程中文件系统不可用,属于正常行为SIGTERM received→shutting down— 进程正常终止(非崩溃、非 OOM)Stopped openclaw-gateway.service— systemd 安全停止服务
2.3 检查是否有 OOM Killer 事件
# 方法一:journalctl 内核日志
journalctl -k | grep -iE "oom|kill|out of memory"
# 方法二:dmesg
dmesg | grep -iE "oom|kill|out of memory"输出:
[ 823.630231] WSL (219 - GnsEngine) ERROR: nft -a list chain ip nat WSLPOSTROUTING killed by signal 13解读:唯一的相关日志是 WSL 内一个 nft(网络过滤)进程被 signal 13 杀死,与 openclaw 完全无关。无 OOM 事件。
Step 3:分析 Shell 历史记录
系统上有两个历史文件:~/.bash_history(bash,记录命令文本)和 ~/.zsh_history(zsh,带 Unix 时间戳)。
3.1 zsh 历史文件格式说明
zsh 历史记录中的每一行格式如下:
: <unix_timestamp>:<elapsed_seconds>;<command>示例:
: 1784025455:0;openclaw gateway restart时间戳 1784025455 是 Unix 时间戳(自 1970-01-01 以来的秒数),可用 date 命令转换为可读时间:
date -d @1784025455 '+%Y-%m-%d %H:%M:%S %Z'
# 输出:2026-07-14 18:37:35 CST3.2 提取目标时间段的所有命令(shell 脚本方式)
# 提取 2026-07-14 的所有 openclaw 相关命令
cat /home/montarius/.zsh_history | while IFS= read -r line; do
ts=$(echo "$line" | grep -oP '^: \K[0-9]+')
cmd=$(echo "$line" | sed 's/^: [0-9]*:[0-9]*;//')
if [ -n "$ts" ]; then
day=$(date -d @"$ts" '+%Y-%m-%d' 2>/dev/null)
if [ "$day" = "2026-07-14" ]; then
echo "$(date -d @"$ts" '+%Y-%m-%d %H:%M:%S') | $cmd"
fi
fi
done 2>/dev/null | grep -E "openclaw|uninstall|rm " | head -403.3 关键发现(7/14 的操作)
# 插件安装和清理
2026-07-14 17:32:50 | openclaw plugins install headroom # 安装 headroom 插件
2026-07-14 17:38:20 | openclaw update # 检查更新
2026-07-14 17:42:38 | curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.5/install.sh | bash # 升级 nvm
2026-07-14 17:43:11 | nvm install 22 # 安装 Node.js v22
2026-07-14 17:45:05 | npm i -g openclaw # 重新安装 openclaw
2026-07-14 17:45:23 | npm i -g openclaw@latest # 安装最新版
2026-07-14 17:55:43 | ps aux | grep openclaw # 检查进程
2026-07-14 17:59:29 | rm -rf ~/.openclaw/extensions/feishu # 删除 feishu 插件目录
2026-07-14 18:06:17 | rm -rf ~/.openclaw/extensions/headroom # 删除 headroom 插件目录
2026-07-14 18:27:00 | pkill -f openclaw # 强制终止旧 gateway
2026-07-14 18:27:06 | find ~/.openclaw -name "*.lock" -o -name "*migration*" 2>/dev/null # 清理锁文件
2026-07-14 18:27:41 | rm -rf ~/.openclaw/.openclaw-install-stage-* # 清理安装残留
2026-07-14 18:27:45 | rm -f ~/.openclaw/*.db-wal ~/.openclaw/*.db-shm # 清理数据库 WAL 文件
2026-07-14 18:37:35 | openclaw plugins uninstall feishu --force # 卸载 feishu 插件
2026-07-14 18:38:33 | openclaw plugins install @openclaw/feishu # 重新安装 feishu
2026-07-14 18:40:00 | nvm use --delete-prefix v22.23.1 # 设置正确的 Node 版本解读:
- 7/14 的操作全部是插件管理(安装/卸载 feishu、headroom)和 nvm 版本升级,没有
npm uninstall openclaw或apt remove openclaw等真正的卸载命令 - 唯一的
uninstall命令是openclaw plugins uninstall feishu --force,这是卸载插件而非主程序 - 所有
rm -rf针对的是~/.openclaw/extensions/(插件目录),不是 openclaw 主程序目录 - 用户确实在 7/14 做了大量清理工作(共涉及 20+ 条命令),但这些都是清理插件、升级版本,不是卸载主程序
3.4 检查 7/17 当天的操作记录
# 提取今天 (2026-07-17) 的所有命令
cat /home/montarius/.zsh_history | while IFS= read -r line; do
ts=$(echo "$line" | grep -oP '^: \\K[0-9]+')
cmd=$(echo "$line" | sed 's/^: [0-9]*:[0-9]*;//')
if [ -n "$ts" ]; then
day=$(date -d @"$ts" '+%Y-%m-%d' 2>/dev/null)
if [ "$day" = "2026-07-17" ]; then
echo "$(date -d @"$ts" '+%Y-%m-%d %H:%M:%S') | $cmd"
fi
fi
done 2>/dev/null | head -30输出:
2026-07-17 08:09:51 | openclaw gateway restart ← 第一次尝试,command not found ❌
2026-07-17 08:10:29 | which openclaw ← 确认命令不存在
2026-07-17 08:12:17 | echo $PATH ← 查看当前 PATH
2026-07-17 08:13:34 | source ~/.zshrc ← 尝试重新加载配置
2026-07-17 08:13:41 | which openclaw ← 仍然找不到
2026-07-17 08:14:52 | npm list -g openclaw ← 检查包是否存在
2026-07-17 08:15:51 | nvm --version ← 检查 nvm 状态
2026-07-17 08:15:56 | nvm list ← 列出 Node 版本
2026-07-17 08:16:06 | nvm use --delete-prefix v22.23.1 ← 激活正确版本
2026-07-17 08:16:14 | which openclaw ← ✅ 现在能找到了!
2026-07-17 08:16:18 | nvm ls
2026-07-17 08:17:04 | node -v
2026-07-17 08:17:17 | which npm
2026-07-17 08:17:29 | npm install -g openclaw ← 重新安装(保证万无一失)
2026-07-17 08:18:28 | openclaw doctor --fix ← 修复配置
2026-07-17 08:19:10 | openclaw gateway restart ← ✅ 成功启动!
2026-07-17 08:24:13 | which openclaw ← 确认持久可用解读:
- 08:09 报
command not found→ 用户推断为被卸载,但实际上包仍在,只是 PATH 中没有 - 08:10–08:14 是排查阶段(检查 PATH、nvm、npm)
- 08:16
nvm use --delete-prefix v22.23.1→which openclaw立刻恢复 ✅ 这是锁死根因的关键 - 08:17 虽然是”重新安装”,但实际上包已经存在,这是出于保险操作的
3.5 验证无 uninstall 命令
# 在全量历史中搜索任何可能的卸载命令
cat /home/montarius/.zsh_history | while IFS= read -r line; do
ts=$(echo "$line" | grep -oP '^: \K[0-9]+')
cmd=$(echo "$line" | sed 's/^: [0-9]*:[0-9]*;//')
if echo "$cmd" | grep -qiE "uninstall|unlink|remove.*openclaw"; then
dt=$(date -d @"$ts" '+%Y-%m-%d %H:%M:%S')
echo "$dt | $cmd"
fi
done 2>/dev/null输出:(无任何匹配项)
同样检查 bash_history 中是否有卸载命令:
grep -iE "uninstall|remove.*openclaw|unlink" /home/montarius/.bash_history输出:(无任何匹配项)
Step 4:分析系统包管理器日志
因为 openclaw 不是系统包(非 apt/dpkg 安装的),这个步骤主要是为了确认系统层面没有任何卸载操作,以及检查是否有系统回滚或依赖冲突。
4.1 检查 dpkg 日志
# 查看 7/16 的 dpkg 变更
grep "2026-07-16" /var/log/dpkg.log输出:(无任何输出——7/16 没有任何 dpkg 操作)
4.2 检查 apt history 日志
cat /var/log/apt/history.log | tail -50输出:
Start-Date: 2026-07-15 08:42:15
Commandline: /usr/bin/unattended-upgrade
Upgrade: libasound2t64:amd64 (1.2.11-1ubuntu0.2, 1.2.11-1ubuntu0.3)
End-Date: 2026-07-15 08:42:16
Start-Date: 2026-07-15 08:42:17
Commandline: /usr/bin/unattended-upgrade
Upgrade: openssh-client:amd64 (1:9.6p1-3ubuntu13.16, 1:9.6p1-3ubuntu13.18)
End-Date: 2026-07-15 08:42:18
Start-Date: 2026-07-17 08:21:59
Commandline: /usr/bin/unattended-upgrade
Upgrade: python3-idna:amd64 (3.6-2ubuntu0.1, 3.6-2ubuntu0.2)
End-Date: 2026-07-17 08:21:59
Start-Date: 2026-07-17 08:22:01
Commandline: /usr/bin/unattended-upgrade
Upgrade: libheif1:amd64 (1.17.6-1ubuntu4.4, 1.17.6-1ubuntu4.6), ...
End-Date: 2026-07-17 08:22:02
Start-Date: 2026-07-17 08:22:03
Commandline: /usr/bin/unattended-upgrade
Upgrade: vim:amd64 (2:9.1.0016-1ubuntu7.17, 2:9.1.0016-1ubuntu7.18), ...
End-Date: 2026-07-17 08:22:06
Start-Date: 2026-07-17 08:22:06
Commandline: /usr/bin/unattended-upgrade
Upgrade: wget:amd64 (1.21.4-1ubuntu4.1, 1.21.4-1ubuntu4.3)
End-Date: 2026-07-17 08:22:07解读:7/16 没有任何 apt 操作。7/15 和 7/17 的变更都是 unattended-upgrades 自动安全更新(libasound、openssh-client、python3-idna、vim、wget 等)——与 openclaw 无关。
Step 5:分析身份认证日志 (auth.log)
检查是否有 sudo 或 root 权限下的 uninstall 操作,排除安全事件可能性。
# 查看 7/16 的身份认证日志
cat /var/log/auth.log | grep "2026-07-16"输出:
2026-07-16T00:00:06.395748+08:00 MS-Zephyrus16 CRON[200787]: pam_unix(cron:session): session opened for user montarius(uid=1000) by montarius(uid=0)
2026-07-16T00:00:06.656527+08:00 MS-Zephyrus16 CRON[200787]: pam_unix(cron:session): session closed for user montarius
2026-07-16T00:10:06.203752+08:00 MS-Zephyrus16 CRON[202512]: pam_unix(cron:session): session opened for user montarius(uid=1000) by montarius(uid=0)
2026-07-16T00:10:06.509337+08:00 MS-Zephyrus16 CRON[202512]: pam_unix(cron:session): session closed for user montarius
2026-07-16T00:17:05.643630+08:00 MS-Zephyrus16 CRON[203677]: pam_unix(cron:session): session opened for user root(uid=0) by root(uid=0)
2026-07-16T00:17:05.646844+08:00 MS-Zephyrus16 CRON[203677]: pam_unix(cron:session): session closed for user root
2026-07-16T00:20:06.311747+08:00 MS-Zephyrus16 CRON[204173]: pam_unix(cron:session): session opened for user montarius(uid=1000) by montarius(uid=0)
2026-07-16T00:20:06.494510+08:00 MS-Zephyrus16 CRON[204173]: pam_unix(cron:session): session closed for user montarius
...解读:全部是 CRON 定时任务会话的 open/close 事件,只有两种用户:
montarius(uid=1000)— 用户自身的 cron 任务(session-tagger,每 10 分钟执行一次)root(uid=0)— root 的 cron 任务
没有任何 sudo 执行记录、没有任何 apt-get/dpkg 提权操作。
Step 6:交叉验证关机和重启事件
通过 last -x 和 who -b 确定系统的完整运行和重启历史。
# 查看系统启动记录
who -b
# 查看完整的运行级别变更历史
last -x | head -20输出:
system boot 2026-07-17 08:07
runlevel (to lvl 5) 6.6.87.2-microso Fri Jul 17 08:08 still running
reboot system boot 6.6.87.2-microso Fri Jul 17 08:07 still running
shutdown system down 6.6.87.2-microso Fri Jul 17 00:45 - 08:07 (07:22)
runlevel (to lvl 5) 6.6.87.2-microso Tue Jul 14 18:25 - 00:45 (2+06:19)
reboot system boot 6.6.87.2-microso Tue Jul 14 18:25 - 00:45 (2+06:19)
shutdown system down 6.6.87.2-microso Tue Jul 14 18:25 - 18:25 (00:00)
runlevel (to lvl 5) 6.6.87.2-microso Tue Jul 14 16:30 - 18:25 (01:54)
reboot system boot 6.6.87.2-microso Tue Jul 14 16:30 - 18:25 (01:54)
runlevel (to lvl 5) 6.6.87.2-microso Thu Jul 9 12:48 - 16:30 (5+03:41)
reboot system boot 6.6.87.2-microso Thu Jul 9 12:48 - 18:25 (5+05:36)解读:
系统运行时间表:
──────────────────────────────────────────────────────
7/8 08:15 ─→ 08:22 (0h07m)
7/8 08:28 ─→ 7/9 12:48 (1d04h)
7/9 12:48 ─→ 7/14 18:25 (5d05h) ← 最长运行
7/14 18:25 ─→ 7/17 00:45 (2d06h) ← 本次关键周期 ↑
↓ ★ 关机 ★
7/17 08:07 ─→ 至今 ← 本次重启后出问题
──────────────────────────────────────────────────────关键时间点:
- 7/14 18:25 系统重启(当时 openclaw 正常工作)
- 7/17 00:45 系统 shutdown(openclaw gateway 收到 SIGTERM 正常停止)
- 7/17 08:07 系统重启(这是问题发生的时间点——重启后 nvm 未激活)
排查结论:根因定位
根因:nvm Node.js 版本未自动激活
# openclaw 的实际安装路径
# npm 全局包位置:
/home/montarius/.nvm/versions/node/v22.23.1/lib/node_modules/openclaw/
# 对应的二进制链接(symlink):
/home/montarius/.nvm/versions/node/v22.23.1/bin/openclaw
# nvm 的安装路径(从 ~/.zshrc 配置确认):
export NVM_DIR="$HOME/.nvm" # line 128
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # line 129
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # line 130问题链:
WSL 关机 (7/17 00:45) ← 用户关闭 WSL/Windows 导致
↓
WSL 重启 (7/17 08:07) ← 用户重新打开
↓
Shell 启动(zsh)
↓
~/.zshrc 执行 → nvm.sh 理论上应被 source
↓
但 nvm 的 default alias **可能没有设置**,或者 ~/.zshrc 的 nvm 初始化
在非交互模式下未被正确调用
↓
PATH 中不包含 /home/montarius/.nvm/versions/node/v22.23.1/bin/
(该路径由 nvm use 激活后动态添加到 PATH)
↓
which openclaw → 找不到该命令
↓
用户误认为 openclaw 被卸载为什么 nvm 版本没激活?
有几种可能性:
- nvm default alias 未设置:执行
nvm alias default v22.23.1后才算设好默认版本,否则 nvm 不会在 shell 启动时自动切换 - 首次打开的 Shell 可能不是交互式:WSL 启动后的某些自动化任务可能使用非交互 shell
- ~/.zshrc 条件判断分支:某些
.zshrc配置在不同条件下(本地/SSH)加载不同的 PATH --delete-prefix的必要性:从输出看,用户最终用了nvm use --delete-prefix而非nvm use,说明之前存在 prefix 冲突
关键证据:
从 shell history 可以看到精确的修复过程:
08:15:56 | nvm list ← 查看已安装版本
08:16:06 | nvm use --delete-prefix v22.23.1 ← 激活版本(需要 --delete-prefix!)
08:16:14 | which openclaw ← ✅ 立刻找到了!nvm use 之后立刻 which openclaw 成功,这直接证明了问题确实出在 nvm 版本激活上。
问题复原场景
“作案”过程复原:
你在 7/14 晚上做了一些插件清理和 nvm 升级操作:
├─ 安装 nvm 0.40.5(之前是旧版)
├─ nvm install 22(安装 Node 22)
├─ 重新安装 openclaw
└─ 删除插件目录、清理残留
然后系统持续正常运行了约 2 天(7/14 18:25 → 7/17 00:45)
7/17 凌晨你关闭了 WSL(或 Windows 关机/休眠)
→ openclaw gateway 收到 SIGTERM,正常停止
7/17 早上你重新打开 WSL
→ WSL 启动
→ systemd 启动 openclaw-gateway.service(服务本身正常,用了硬编码路径)
→ 但你打开的交互式 Shell 中,nvm 没有激活 Node 22
→ PATH 中没有 node/npm 的 bin 目录
→ 你运行 openclaw → command not found
后续排查:
→ which openclaw → 找不到
→ npm list -g openclaw → 发现包还在 ✅
→ nvm use → 激活版本
→ which openclaw → ✅ 恢复了!
→ 保险起见还是重新安装了一次为什么不是真正的卸载
| 排除项 | 证据 | 结论 |
|---|---|---|
| npm uninstall | Shell history 中没有任何 npm uninstall 命令 | 非卸载 |
| apt/dpkg 卸载 | dpkg.log 中 7/16 无记录,apt history 只有 unattended-upgrades | 非系统包操作 |
| OOM Killer | journalctl -k 和 dmesg 无 OOM 事件 | 非进程崩溃 |
| 用户手动删除 | 所有 rm 操作针对的是插件目录,非主程序 | 非手动删除 |
| 系统回滚 | apt history.log 只有普通安全更新 | 非系统变更 |
| 恶意软件/入侵 | auth.log 无异常 sudo/root 操作 | 非安全事件 |
| 磁盘损坏/坏道 | 磁盘 I/O 日志无异常 | 非硬件问题 |
完整事件时间线
2026-07-09
├─ 16:34 安装 nvm、Node.js、配置 node 版本
└─ 16:55 npm install -g openclaw
2026-07-12
└─ 09:44 openclaw gateway restart
2026-07-14
├─ 17:23 开始处理 headroom 插件 (openclaw plugins install headroom)
├─ 17:42 nvm 操作 (升级到 v0.40.5)
├─ 17:43 nvm install 22
├─ 17:45 npm install -g openclaw & openclaw@latest
├─ 17:59 rm -rf ~/.openclaw/extensions/feishu ← 删除插件目录
├─ 18:06 rm -rf ~/.openclaw/extensions/headroom ← 删除插件目录
├─ 18:27 pkill -f openclaw ← 强制重启 gateway
├─ 18:27 清理:锁文件、安装残留、数据库 WAL
├─ 18:37 openclaw plugins uninstall feishu --force ← 卸载 feishu 插件
├─ 18:38 openclaw plugins install @openclaw/feishu ← 重新安装
└─ 18:40 nvm use --delete-prefix v22.23.1 ← 设置 Node 版本
2026-07-15 ← openclaw 正常运行一整天
├─ 08:44 openclaw gateway restart
├─ 11:22 openclaw gateway restart
├─ 14:46 openclaw gateway restart
└─ 17:14 openclaw gateway restart
2026-07-16 ← openclaw 正常运行(7/15 22:22 启动后持续运行)
├─ 00:05~22:19 节点进程 98829 持续活跃(1142 条日志)
├─ 01:35~全天 memory sync failed(OpenAI key 缺失,已知问题)
├─ 11:07~11:14 LLM idle timeout(模型超时,不影响进程)
├─ 19:47 feishu/lark 连接 ping_timeout 出错
└─ 全天 session-tagger cron 每 10分钟运行一次
2026-07-17 (今天)
├─ 00:18 openclaw gateway 正常运行(tool policy 更新)
├─ 00:44 webchat 断开(WSL 关机前兆)
├─ 00:45 ★★★ 系统关机 (WSL shutdown) ★★★
│ └─ openclaw-gateway.service 收到 SIGTERM → 正常停止
├─ 08:07 ★★★ 系统重启 (WSL boot) ★★★
│ └─ ⚠️ 此时 nvm 默认版本未激活 → openclaw 命令不可用
├─ 08:09 openclaw gateway restart → command not found ❌ ← 用户报告的时刻
├─ 08:10 which openclaw → 找不到
├─ 08:14 npm list -g openclaw → 发现包仍在 ✅
├─ 08:16 nvm use --delete-prefix v22.23.1 ✅ ← 根因确认
├─ 08:17 npm install -g openclaw(保险操作)
├─ 08:18 openclaw doctor --fix(修复配置)
└─ 08:19 openclaw gateway restart → 成功启动 ✅修复步骤
已执行的操作
# 1. 激活正确的 Node.js 版本(核心修复)
nvm use --delete-prefix v22.23.1
# 注:--delete-prefix 参数必要,说明之前可能存在 nvm prefix 冲突
# 2. 确认 node/npm 正常
node -v # v22.23.1
npm -v # 10.x.x
which npm # 确认 npm 在 PATH 中
# 3. 重新安装 openclaw 全局包(保险操作,覆盖安装)
npm install -g openclaw
# 4. 运行诊断修复(修复可能残缺的配置)
openclaw doctor --fix
# 5. 重启 gateway
openclaw gateway restart
# 6. 验证持久可用
which openclaw
openclaw --version建议的预防措施
1. 设置 nvm 默认版本
# 设置默认版本——下次 shell 启动时会自动切换
nvm alias default v22.23.1
# 验证默认版本已设置
nvm ls
# 输出应看到:
# v22.23.1
# default -> v22.23.12. 验证 ~/.zshrc 中的 nvm 初始化配置
# 检查 ~/.zshrc 中是否有以下配置
grep -n "NVM_DIR\|nvm.sh" ~/.zshrc期望输出(当前已有):
128:export NVM_DIR="$HOME/.nvm"
129:[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
130:[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion3. 在 ~/.profile 中也添加 nvm 初始化
WSL 启动时 ~/.profile 会被读取,而 ~/.zshrc 只在交互式 zsh 会话中读取。为保险起见建议也在 ~/.profile 中添加:
# ~/.profile 中添加
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"4. 验证开机自启服务
# 检查 openclaw gateway 的 systemd 用户服务状态
systemctl --user status openclaw-gateway.service
# 注意:systemd service 使用硬编码的绝对路径
# 见 ~/.config/systemd/user/openclaw-gateway.service 中的 ExecStart
# 所以服务本身会正常启动,不受 nvm 影响5. 手动诊断工具
# 遇到类似情况时,快速诊断命令链
alias diag_openclaw='echo "--- PATH check ---"; echo $PATH | tr ":" "\n" | grep nvm; echo "--- npm global ---"; npm list -g openclaw 2>/dev/null; echo "--- which ---"; which openclaw; echo "--- nvm ---"; nvm current'附录
命令参考速查表
Step 1:当前状态检查
# 命令是否存在
which openclaw
# npm 全局包
npm list -g openclaw
# 查看 nvm 状态
nvm --version
nvm list
nvm current
node -vStep 2:系统日志
# 查看时间段内节点进程日志
journalctl --since "2026-07-16 00:00:00" --until "2026-07-16 23:59:59" --no-pager | grep "node\[98829\]"
# 查看关机时刻日志
journalctl --since "2026-07-17 00:44:00" --until "2026-07-17 00:46:00" --no-pager
# 检查 OOM
journalctl -k | grep -iE "oom|kill|out of memory"
dmesg | grep -iE "oom|kill|out of memory"Step 3:Shell 历史
# zsh 历史时间戳转换(单条)
date -d @1784025455 '+%Y-%m-%d %H:%M:%S %Z'
# 批量提取某天的历史
cat /home/montarius/.zsh_history | while IFS= read -r line; do
ts=$(echo "$line" | grep -oP '^: \K[0-9]+')
cmd=$(echo "$line" | sed 's/^: [0-9]*:[0-9]*;//')
if [ -n "$ts" ]; then
day=$(date -d @"$ts" '+%Y-%m-%d' 2>/dev/null)
if [ "$day" = "2026-07-17" ]; then
echo "$(date -d @"$ts" '+%Y-%m-%d %H:%M:%S') | $cmd"
fi
fi
done 2>/dev/nullStep 4:包管理器日志
# dpkg 日志
cat /var/log/dpkg.log | grep "2026-07-16"
# apt 历史
cat /var/log/apt/history.log | tail -50Step 5:身份认证日志
cat /var/log/auth.log | grep "2026-07-16"Step 6:系统重启记录
who -b # 最近一次启动时间
last -x | grep -E "reboot|shutdown|runlevel" # 完整启动/关闭历史nvm 相关操作
# 查看当前版本
nvm current
# 列出所有版本
nvm ls
# 激活版本(有 prefix 冲突时加 --delete-prefix)
nvm use v22.23.1
nvm use --delete-prefix v22.23.1 # 处理 prefix 冲突
# 设置默认版本
nvm alias default v22.23.1
# 查看 nvm 配置
echo $NVM_DIR
cat ~/.zshrc | grep nvm日志文件路径索引
| 日志 | 路径 | 用途 |
|---|---|---|
| systemd 日志 | journalctl(命令行工具) | 系统服务、节点进程、关机事件 |
| 内核日志 | journalctl -k / dmesg | OOM Killer、硬件错误 |
| apt 历史 | /var/log/apt/history.log | apt 安装/升级/删除记录 |
| dpkg 操作 | /var/log/dpkg.log | 包管理器详细操作日志 |
| 身份认证 | /var/log/auth.log | sudo、su、登录等鉴权事件 |
| Zsh 历史 | ~/.zsh_history | 用户交互式 shell 命令(带时间戳) |
| Bash 历史 | ~/.bash_history | bash 命令记录(无时间戳) |
| npm 全局包 | npm list -g | npm 全局安装的包列表 |
| npm 日志 | ~/.npm/_logs/*.log | npm 安装/卸载详细日志 |
| OpenClaw 日志 | /tmp/openclaw/openclaw-*.log | gateway 进程日志 |
| 用户 serivce 配置 | ~/.config/systemd/user/openclaw-gateway.service | systemd 服务定义 |
| session-tagger 日志 | ~/.openclaw/workspace/skills/session-tagger/runner.log | 自动标签 cron 任务日志 |
systemd 服务配置原文
# /home/montarius/.config/systemd/user/openclaw-gateway.service
[Unit]
Description=OpenClaw Gateway (v2026.7.1)
After=network-online.target
Wants=network-online.target
StartLimitBurst=5
StartLimitIntervalSec=60
[Service]
ExecStart=/home/montarius/.nvm/versions/node/v22.23.1/bin/node \
/home/montarius/.npm-global/lib/node_modules/openclaw/dist/index.js \
gateway --port 18789
Restart=always
RestartSec=5
RestartPreventExitStatus=78
TimeoutStopSec=30
TimeoutStartSec=30
SuccessExitStatus=0 143
OOMPolicy=continue
KillMode=control-group
Environment=HOME=/home/montarius
Environment=TMPDIR=/tmp
Environment=NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt
Environment=PATH=/home/montarius/.nvm/versions/node/v22.23.1/bin:\
/home/montarius/.npm-global/bin:/usr/local/bin:/usr/bin:/bin:\
/home/montarius/.nvm/current/bin
Environment=OPENCLAW_GATEWAY_PORT=18789
Environment=OPENCLAW_SYSTEMD_UNIT=openclaw-gateway.service
Environment="OPENCLAW_WINDOWS_TASK_NAME=OpenClaw Gateway"
Environment=OPENCLAW_WINDOWS_TASK_HIDDEN_LAUNCHER=1
Environment=OPENCLAW_SERVICE_MARKER=openclaw
Environment=OPENCLAW_SERVICE_KIND=gateway
Environment=OPENCLAW_SERVICE_VERSION=2026.7.1
[Install]
WantedBy=default.target注意:systemd 服务中
ExecStart使用硬编码的绝对路径(/home/montarius/.nvm/versions/node/v22.23.1/bin/),因此服务在系统启动时能正常启动,不受用户的交互式 shell PATH 影响。这解释了为什么systemctl --user status openclaw-gateway.service显示服务在运行,但用户在终端中输入openclaw却找不到命令——这是用户 shell 环境变量的问题,不是服务本身的问题。
声明:本文撰写于排查事件当天(2026-07-17),为安全取证过程的完整记录。文中所有日志时间戳均为 Asia/Shanghai (UTC+8) 时区。