现象
8 月 11 号早上起来,发现 Discord 上 @ Hermes 完全没有回应。
$ systemctl status hermes
● hermes.service - Hermes Agent
Active: active (running) since Mon 2026-08-11 07:15:21 CST
Main PID: 2847 (python3)
Memory: 184.0M看起来一切正常。但 Discord 上什么反应都没有。
排查
第一步:看日志
$ journalctl -u hermes --since "1 hour ago" -n 50
Aug 11 07:15:21 hermes-yuxi systemd[1]: Started Hermes Agent.
Aug 11 07:15:22 hermes python3[2847]: [INFO] connecting to discord gateway...
Aug 11 07:15:25 hermes python3[2847]: [ERROR] FileNotFoundError: [Errno 2] No such file or directory: '/home/ezra/.config/hermes/credentials.json'
Aug 11 07:15:25 hermes systemd[1]: hermes.service: Main process exited, code=exited, status=1/FAILURE
Aug 11 07:15:25 hermes systemd[1]: hermes.service: Scheduled restart job, restart counter is at 1.
Aug 11 07:15:26 hermes systemd[1]: Started Hermes Agent.
Aug 11 07:15:26 hermes python3[2901]: [INFO] connecting to discord gateway...
Aug 11 07:15:28 hermes python3[2907]: [ERROR] FileNotFoundError: ...哦——一直在 restart。
第二步:为什么 status 报 active?
Active: active (running) 只意味着 systemd 正在尝试保持它跑着。如果进程崩了,systemd 立刻拉起新的——只要重启间隔 < 几秒,status 永远是 active (running)。
这是 systemd 的设计:Type=simple 默认行为就是 restart-forever。
第三步:根因
systemd unit file 里:
[Service]
WorkingDirectory=/home/ezra
ExecStart=/usr/bin/python3 -m hermes --yolo看起来正常,但实际用户的 home 是 /home/ezra,credentials 文件在 /home/ezra/.hermes/credentials.json——
不对,等等,错误信息说的是 /home/ezra/.config/hermes/credentials.json。
我看了一下 hermes 的代码:
# hermes/config.py
CREDENTIALS_PATH = Path(os.environ.get('HERMES_HOME', '~/.config/hermes')) / 'credentials.json'但实际的配置在 ~/.hermes/。两个不同的路径。
问题:systemd 启动时 HOME=/root(默认),所以 ~ 展开成 /root,然后 ~/.config/hermes/credentials.json → /root/.config/hermes/credentials.json,找不到。
而我们的实际 credentials 在 /home/ezra/.hermes/credentials.json。
修复
[Service]
User=ezra
WorkingDirectory=/home/ezra
Environment="HOME=/home/ezra"
Environment="HERMES_HOME=/home/ezra/.hermes"
ExecStart=/usr/bin/python3 -m hermes --yolo
Restart=on-failure
RestartSec=10User=ezra让 systemd 以 ezra 身份跑Environment="HOME=..."显式设 homeEnvironment="HERMES_HOME=..."显式告诉 hermes 配置文件在哪
之后:
$ systemctl restart hermes
$ journalctl -u hermes -n 5
Aug 11 08:22:14 hermes-yuxi systemd[1]: Started Hermes Agent.
Aug 11 08:22:15 hermes python3[3127]: [INFO] connecting to discord gateway...
Aug 11 08:22:16 hermes python3[3127]: [INFO] gateway connected
Aug 11 08:22:16 hermes python3[3127]: [INFO] ready好了,Discord 能回了。
经验
- systemd
active (running)不等于 service 工作 —— 进程崩了 systemd 立刻拉起,看起来一切正常 - 看
journalctl不看systemctl status—— status 是表象,journal 是真相 Type=simple+ 默认Restart=always会导致 restart loop —— 配Restart=on-failure+RestartSec=10s让失败有迹可循- systemd service 一定要显式设
User=和Environment=—— 别依赖默认值
🎵 Listening companion
“在跑”不等于“在工作”。这两个词之间的距离,就是日志和 status 之间的差距。