需在 systemd 服务中调用 systemd-notify --ready 发送 ready=1 通知,前提是服务单元配置 type=notify 和 notifyaccess=all,并确保脚本在主进程或其子进程中执行且能访问 $notify_socket。

要在 systemd 服务中通过自定义脚本通知 systemd 服务已就绪,需在脚本中调用 systemd-notify 发送 READY=1。前提是服务单元文件启用通知机制,且脚本运行环境能访问 systemd-notify 工具。
确保服务单元启用 NotifyAccess 和 Type=notify
systemd 必须知道该服务会主动发送状态信号,否则会忽略 systemd-notify 请求。关键配置项:
- Type=notify:告诉 systemd 该服务使用通知协议(而非 fork、simple 等)
-
NotifyAccess=all(或
main/exec):允许服务进程(或其子进程)调用systemd-notify;all最宽松,适用于脚本中直接调用 - 可选但推荐:TimeoutSec= 设置合理超时,避免因未发 READY 导致启动卡住
示例 /etc/systemd/system/myapp.service:
[Unit] Description=My Custom App <p>[Service] Type=notify NotifyAccess=all ExecStart=/usr/local/bin/myapp-start.sh Restart=on-failure TimeoutSec=30</p><p>[Install] WantedBy=multi-user.target </p>
在脚本中调用 systemd-notify 发送 READY=1
脚本完成初始化后(如端口监听就绪、配置加载完毕),执行:
systemd-notify --ready --status="Started myapp"
其中 --ready 等价于 READY=1,--status 是可选的描述性信息(会显示在 systemctl status 中)。注意:
- 必须在服务主进程(即
ExecStart启动的进程)或其子进程中执行,且该进程需有权限访问$NOTIFY_SOCKET(systemd 自动注入) - 若脚本使用
bash或其他 shell,确保systemd-notify在$PATH中(通常位于/usr/bin/systemd-notify) - 建议加简单校验,避免 silent fail:
if command -v systemd-notify > /dev/null; then
systemd-notify --ready --status="Application ready"
else
echo "Warning: systemd-notify not available, skipping notify" >&2
fi
验证是否生效
重载并重启服务后,检查状态:
sudo systemctl daemon-reload sudo systemctl restart myapp.service sudo systemctl status myapp.service
成功时应看到类似输出:
● myapp.service - My Custom App
Loaded: loaded (/etc/systemd/system/myapp.service; enabled)
Active: active (running) since ...
Docs: man:systemd-notify(1)
Main PID: 12345 (myapp-start.sh)
Status: "Started myapp"
Tasks: 1
Memory: 1.2M
CPU: 123ms
CGroup: /system.slice/myapp.service
└─12345 /bin/bash /usr/local/bin/myapp-start.sh
关键点:Active: active (running) 表明 systemd 已收到 READY;Status: 行显示你传入的描述文本。
常见问题与避坑提示
如果服务始终卡在 activating (start) 或超时失败,请检查:
- 脚本是否真的执行了
systemd-notify --ready(加echo或日志确认) - 服务类型是否为
Type=notify(误设为simple会导致 systemd 不等待 READY) -
NotifyAccess是否足够(设为none或未设置将拒绝通知) - 脚本是否后台化或
exec替换了进程(如exec python app.py后,原 shell 进程消失,可能导致systemd-notify调用失效;应确保通知在主进程生命周期内发出) - 使用
sudo journalctl -u myapp.service -f查看实时日志,确认是否有 “Failed to send notification message” 类错误











