故障现象
在全新的 Linux 服务器(如 Ubuntu 22.04/24.04)上执行 openclaw gateway install 命令时,安装过程会中断并提示服务检查失败。尽管系统已正确配置 systemd user services,但 OpenClaw 网关服务尚未安装。
报错详情
Gateway service check failed: Error: systemctl is-enabled unavailable: Command failed: systemctl --user is-enabled openclaw-gateway.service
核心原因分析
问题出在 dist/systemd-*.js 中的 isSystemdServiceEnabled() 函数。它调用 execFileUtf8("systemctl", ["--user", "is-enabled", "openclaw-gateway.service"])。当服务不存在时,systemctl 返回退出码 4 和 stdout "not-found\n"。
然而,execFileUtf8 在处理非零退出码时,会用 error.message 替换空的 stderr。这导致后续 readSystemctlDetail() 优先读取了被覆盖的错误消息,而不是 "not-found"。于是 isSystemdUnitNotEnabled(detail) 无法识别该状态,直接抛出异常。
复现路径
- 准备全新 Ubuntu 服务器,确保 systemd user services 已启用。
- 通过 npm 全局安装 openclaw。
- 运行
openclaw gateway install --port 18789 --force。 - 观察控制台报错。
预期逻辑
gateway install 应当识别退出码 4 或 "not-found" 为'服务尚未安装',从而继续执行服务文件的创建流程。
代码层修复思路
官方可从以下三个方向优化:
- 修改
execFileUtf8:不再用 error.message 替换空的 stderr,或分开存储两者。 - 调整
readSystemctlDetail:当 stderr 包含 "Command failed" 时,优先使用 stdout。 - 完善
isSystemdServiceEnabled:直接检查 stdout 中的 unit-not-found 模式。
临时规避方案
在调用 openclaw gateway start 前,手动创建 systemd user service 文件即可绕过此检查。
mkdir -p ~/.config/systemd/user
cat > ~/.config/systemd/user/openclaw-gateway.service << EOF
[Unit]
Description=OpenClaw Gateway
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=$(which node) $(realpath $(which openclaw)) gateway run --port 18789
Restart=always
RestartSec=5
KillMode=process
WorkingDirectory=$HOME/.openclaw
[Install]
WantedBy=default.target
EOF
systemctl --user daemon-reload
systemctl --user enable openclaw-gateway.service
systemctl --user start openclaw-gateway.service

