目录
你启动了一次训练、一整套测试、一个 docker build,或者一个 AI 编程助手去处理一项耗时的任务。然后你只有两个糟糕的选项:坐着盯进度条,或者走开二十分钟回来发现它在第九十秒就失败了。
其实还有第三个选项,一行就够。
那一行
在 Echobell 里建一个频道,复制它的 webhook URL,然后接在你要跑的命令后面:
pnpm build; curl -sS -X POST https://hook.echobell.one/t/YOUR_TOKEN \
-H 'content-type: application/json' \
-d '{"title":"构建结束","body":"echobell-web"}'
注意这里是 ; 而不是 &&。用 && 的话,只有命令成功时才会发通知——而这恰好是反的:失败才是你最想知道的那种情况。
把退出码也带上
一条只说「结束了」的通知只讲了一半。把状态一起捕获:
pnpm build; s=$?; curl -sS -X POST https://hook.echobell.one/t/YOUR_TOKEN \
-H 'content-type: application/json' \
-d "{\"title\":\"构建 $([ $s -eq 0 ] && echo 成功 || echo 失败)\",\"status\":\"$s\"}"
s=$? 必须紧跟在命令后面。中间夹任何东西——包括 [ 这个测试命令本身——都会把 $? 覆盖掉。
做成一个 shell 函数
每次都手打这一串就失去意义了。把这个放进 ~/.zshrc 或 ~/.bashrc:
notify() {
"$@"
local status=$?
curl -sS -X POST "$ECHOBELL_HOOK" \
-H 'content-type: application/json' \
-d "{\"command\":\"$*\",\"status\":\"$status\",\"host\":\"$(hostname -s)\"}" \
>/dev/null
return $status
}
在 shell 配置里设置 ECHOBELL_HOOK——更好的做法是别把它放进会提交的 dotfiles 仓库,而是从一个不纳入版本控制的文件里 export。然后:
notify pnpm test
notify cargo build --release
notify python train.py
结尾那句 return $status 很重要:它让 notify 保持透明,所以 notify make && ./deploy.sh 依然按你预期的方式工作。
配合上面的 payload,频道模板可以写成:
标题
{{command}} · {{status}}
正文
在 {{host}} 上
只有失败时才叫我
大多数运行都会成功,你并不需要听到它们。用两个频道能干净地解决:一个普通频道收全部,一个来电频道加条件:
status != "0"
把值得你从床上爬起来的那些任务指向第二个频道,成功的运行就安静地过去了。
让它扛得住合上笔记本和断掉的 SSH
如果命令跑在 SSH 上,合上笔记本会杀掉这个 shell,通知也就永远不会发出去。两种解法:
tmux —— 在会话里启动然后 detach:
tmux new -d -s build 'notify pnpm build'
nohup —— 临时跑一次:
nohup bash -c 'notify pnpm build' >/dev/null 2>&1 &
两种方式都能让进程活过你的连接,通知会照常送达,不管你还连着没有。
AI 编程助手
同样的模式也适用于一个在处理长任务的 CLI 助手:
notify codex exec "重构支付模块并跑一遍测试"
至于那些跑到一半停下来等人的助手——比如需要审批、需要授权确认——完成通知是错的工具,因为它根本还没完成。那种情况需要的是助手自己的 hook 或回调,而且值得一通电话而不是一条推送。把 AI 助手的审批卡点变成一通电话专门讲了这件事,包括 Claude Code 的 Notification hook 和它的 agent_needs_input matcher。
两个都用:hook 负责「我卡住了」,shell 函数负责「我干完了」。
别往通知里放什么
别放命令输出。 把失败构建的最后几行塞进正文很有诱惑力,但请忍住——构建日志里出现 token、连接串和客户数据的频率比大多数人以为的高,而通知正文最终会显示在锁屏上。发退出码就够了,然后自己回终端看。
别把频道 URL 放进公开的 dotfiles 仓库。 拿到这个 URL 的人都能往你的频道发消息。把它放在不纳入版本控制的文件里,并打开 仅 POST,这样一个随手的链接预览也没法触发它。
常见问题
为什么不用 terminal-notifier 或 notify-send?
那些是在跑命令的那台机器上弹通知。你人在跟前时它们没问题。这套方案针对的正是你不在跟前的情况——远程机器、合上的笔记本、另一个房间。
Windows 上能用吗?
模式一样,语法不同。PowerShell 里等价写法是 Invoke-RestMethod -Method Post -Uri $env:ECHOBELL_HOOK -ContentType application/json -Body $json,用 $LASTEXITCODE 代替 $?。
能推到手表上吗?
可以。订阅会送达配对的 Apple Watch,而「构建好了」这件事,手表其实是最合适的形态。
如果命令要跑 12 个小时呢?
这套方案里没有任何超时——命令什么时候返回,curl 就什么时候执行。用 tmux 跑,免得连接断了把进程一起带走。
队友能收到同样的通知吗?
可以。把频道分享出去,每个订阅者自己选通知类型。共用一台训练机的时候很有用,不止一个人关心 GPU 什么时候空出来。
小结
一个 shell 函数、一个频道,只想要失败通知的话再加一个条件。设置大概花两分钟,换回你盯进度条的那二十分钟。
下载 iPhone 版 Echobell 或在 Google Play 获取,然后找一个长到值得你走开的任务试一次。