Ubuntu 18下服务OnFailure触发通知服务无效的问题咨询
我在Ubuntu 18上配置了一个用于获取CSV文件的服务,配置内容如下:
[Unit] Description=Gets CSV OnFailure=pushovercsv.service [Service] ExecStart=/usr/bin/vehicles.sh [Install] WantedBy=multi-user.target
这个服务本身运行正常。我还搭建了一个通知服务pushovercsv.service,希望在第一个服务停止或进入失败状态时,通过Pushover给我发送提醒,其配置如下:
[Unit] Description=PushOver Notification for vehicles CSV Service [Service] Type=simple ExecStart=curl -s --form-string "token=<secret>" --form-string "user=<secret>" --form-string "message=CSV service" https://<pushover api endpoint> [Install] WantedBy=multi-user.target
两个服务单独运行都没问题,但OnFailure=pushovercsv.service似乎没有生效——当我用systemctl stop vehicles.service手动停止第一个服务时,完全收不到Pushover的通知。我想请教:是不是pushovercsv.service需要手动启动才能被触发?还是说它应该在满足条件时自动启动?
嘿,我来帮你梳理下这个问题~
首先得明确OnFailure=的触发逻辑:它只会在服务进入「失败(failed)」状态时才会触发,而你用systemctl stop手动停止服务时,服务会进入「inactive(已停止)」状态,这不属于“失败”范畴,所以自然不会触发通知服务,这是你当前没收到通知的核心原因。
针对不同需求,给你两种解决方案:
1. 仅在服务意外失败时触发通知
这种场景下你的OnFailure=配置本身是正确的,额外注意两点:
- 不需要手动启动
pushovercsv.service,systemd会在触发条件满足时自动启动它执行; - 要确保第一个服务确实会进入
failed状态:只要你的vehicles.sh脚本以非0返回码退出,服务就会被标记为failed。你可以测试一下:在脚本里临时加一行exit 1让它执行失败,然后用systemctl status vehicles.service查看状态,如果显示failed,那pushovercsv.service应该会被正常触发。
另外建议把pushovercsv.service的Type改成oneshot,因为它是一次性执行的短任务,更符合systemd的生命周期管理:
[Service] Type=oneshot ExecStart=curl -s --form-string "token=<secret>" --form-string "user=<secret>" --form-string "message=CSV service failed" https://<pushover api endpoint>
2. 想在服务被手动停止时也触发通知
Ubuntu 18.04的systemd版本是237,不支持较新的OnStop=指令,所以可以用ExecStopPost=来实现:在服务停止后执行一段脚本,判断停止原因再发送通知。
修改第一个服务的[Service]段:
[Service] ExecStart=/usr/bin/vehicles.sh ExecStopPost=/usr/bin/check_and_notify.sh
然后编写/usr/bin/check_and_notify.sh脚本(记得给脚本加执行权限chmod +x /usr/bin/check_and_notify.sh):
#!/bin/bash # 判断服务是否失败,或者是否是非正常停止 if [ "$SERVICE_RESULT" = "failed" ] || [ "$EXIT_CODE" -ne 0 ]; then curl -s --form-string "token=<secret>" --form-string "user=<secret>" --form-string "message=CSV service stopped/failed" https://<pushover api endpoint> fi
最后再明确下:不管是OnFailure还是ExecStopPost触发的服务/脚本,都不需要提前手动启动,systemd会自动调用它们。
备注:内容来源于stack exchange,提问作者Al Grant

