比特币核心在启动与退场这两个时刻,各自留了一个外接命令的接口:-startupnotify=<cmd> 在节点进入服务状态时执行一条外部命令,-shutdownnotify=<cmd> 在节点开始关闭之前执行。帮助文本对后者的提醒格外直白——关闭的需要可能是急务,所以外部命令千万别拖慢进程,不依赖节点交互的命令最好自己转到后台去。这两个参数解决的是同一个实际问题:节点自己不会敲锣打鼓,而运维的人想知道它什么时候开机、什么时候下线。
一、开机钩子的真实触发点
从源码看,启动通知是在初始化收尾阶段把用户给的命令丢进一个独立线程执行,主线程不会等它。这意味着三件事:第一,命令里如果去调用 RPC,节点此刻已经可以应答,因为 HTTP 服务先于通知起停的编排已就绪;第二,通知只发一次,进程活多久它响几声——没有”每小时提醒一次”的语义;第三,既然在分离线程里跑,脚本崩溃不会影响节点,节点也不会因为脚本没跑完而卡住启动。
典型用法有三类。桌面用户常用它弹一条系统通知,确认同步任务已经挂上;服务器运维常用它往聊天工具推一条开机消息,配合进程守护看门狗区分”节点重启过”和”节点没起来”;审计场景则用它记录一个开机时间戳,和日志里的启动行相互印证。帮助文本没承诺这些,但触发时机决定了它们可行。

二、关机钩子为什么要你”小心”
关机通知的实现与开机相反:所有配置的命令各起一个线程,然后主流程等它们全部结束。官方文档因此特别提醒——命令如果卡在跟节点要回应上,就可能把关闭时间拖长。比特币核心关闭时还要把内存池、钱包数据库干净落盘,外部脚本在这里插队抢资源,轻则慢,重则干扰落盘时序。
正确的写法是把不需要交互的部分立刻转到后台,例如把关机事件写进一个本地队列文件就返回;绝不要在 shutdownnotify 里再发 RPC 调用或者循环 bitcoin-cli,那正是帮助文本警告的场景。另外关机钩子支持重复书写多次,语义就是逐个执行,可以分别负责”落一条记录”和”发一条通知”两件事。
三、哪些情况两个钩子都不会响
这两个钩子只覆盖”正常启动完成”和”开始正常关闭”两个瞬间。进程被 kill -9、机器断电、OOM 被内核强杀,关机通知一次都不会执行;同理,启动过程在配置校验阶段就报错退出时,开机通知也不会响,因为节点根本没进入服务状态。所以它们适合做”锦上添花”的事件记录,不适合做唯一的高可用监控手段——判断节点死活,还是要靠对 RPC 或 P2P 端口的主动探测。把钩子当成事件流水,把健康检查当成生命体征,两者分工要分清楚。
四、脚本里该注意什么
命令通过系统外壳执行,路径、引号、环境变量都按 shell 规则处理。日志目录、数据目录的展开在参数解析阶段完成,脚本里再引用环境变量时要显式写全路径,不要假设继承了节点进程的全部环境。命令文本会被写进节点日志,敏感信息别放进去;同理,脚本要写成幂等,重复触发不产生重复副作用,因为守护系统可能让节点在故障恢复期间多次重启。
最后提醒一个安全边界:钩子命令以节点进程同等权限执行,等于给配置文件持有者一个开机自动执行任意命令的入口。配置文件的读写权限要按密钥级别管理,别人能改你的 bitcoin.conf,就能让节点下次开机替他跑脚本。
五、一个可抄的最小配置
在 bitcoin.conf 里写两行即可起步:开机行 -startupnotify=/usr/bin/logger -t bitcoind "started",关机行 -shutdownnotify=/usr/bin/logger -t bitcoind "stopping"。用系统日志记录事件有两个好处:时间戳由系统盖、不依赖外部网络,且与 syslog 的其他条目天然对齐,事后排查重启原因时可以把钩子记录与 systemd 的服务事件并排看。验证方法也简单:重启节点后在系统日志里找那两条记录,时间应分别紧贴启动完成行与关闭开始行。找不到时优先检查命令路径是否绝对路径、脚本是否可执行,这两项是钩子静默失败的最常见原因。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。