宝塔定时任务失败不通知是因为默认只记录日志且仅凭退出码0判断成功,需手动集成server酱:用trap捕获err、绝对路径调用curl以x-www-form-urlencoded格式推送,并注意环境变量与证书问题。

定时任务执行失败为什么收不到通知
宝塔面板的计划任务默认只记录日志,不主动告警。即使 shell 脚本执行出错(比如命令不存在、权限不足、网络超时),只要脚本本身退出码是 0,宝塔就认为“成功”,不会触发任何提醒。Server酱不是宝塔内置功能,必须手动在脚本里调用,且得确保失败路径也能走到推送逻辑。
Server酱微信推送必须用 curl 发起 POST 请求
Server酱要求以 application/x-www-form-urlencoded 格式发送 text 和 desp 字段,curl 是最轻量可靠的调用方式。不能只写 echo 或用 wget 拼 GET 链接(v1 版本已不支持 GET 推送)。
- 推送 URL 是
https://sctapi.ftqq.com/<code>YOUR_SCKEY.send,YOUR_SCKEY要替换成你在 Server酱申请的真实 key -
text字段限制 32 字,建议填固定标题如【宝塔定时任务告警】 -
desp放具体内容,可包含错误信息、时间、脚本名,用$(date +'%F %T')获取时间戳 - 必须加
-s -m 10参数:静默模式 + 10 秒超时,避免阻塞主任务
如何让失败时也触发推送(关键逻辑)
不能只在脚本末尾无条件推送——那样成功和失败都发,信息过载。要利用 shell 的 $? 或 set -e + trap 捕获异常。推荐用 trap,它能覆盖语法错误、命令未找到等早期失败场景。
#!/bin/bash
SCKEY="SCTxxxxxxxxxxxxxxxxxxxxx"
PUSH_URL="https://sctapi.ftqq.com/${SCKEY}.send"
<p>trap 'curl -s -m 10 --data "text=【宝塔定时任务告警】&desp=脚本异常退出,时间:$(date +'"'%F %T'"')\n任务:$(basename "$0")\n错误码:$?" $PUSH_URL > /dev/null 2>&1' ERR</p><h1>你的实际任务内容,例如:</h1><p>/usr/bin/php /www/wwwroot/test.com/artisan schedule:run >> /www/wwwlogs/schedule.log 2>&1</p><h1>成功后也可选推一次(非必须)</h1><p>if [ $? -eq 0 ]; then
curl -s -m 10 --data "text=【宝塔定时任务完成】&desp=执行成功,时间:$(date +'%F %T')\n任务:$(basename "$0")" $PUSH_URL > /dev/null 2>&1
fi</p>
常见踩坑点:权限、环境变量、PATH 不一致
宝塔计划任务运行在最小化 shell 环境中,crond 用户是 www,没有交互式 shell 的 PATH 和别名。很多脚本本地测试正常,一放宝塔就报 command not found。
- 所有命令必须写绝对路径:
/usr/bin/curl,而不是curl;/usr/bin/php而非php - Server酱推送失败时,
curl可能因缺少ca-certificates报 SSL 错误,可在 curl 后加--insecure(仅调试用,生产环境应修复证书) - 脚本开头加
set -u和set -o pipefail,避免未定义变量或管道中间失败被忽略 - 宝塔日志里看到
Bad file descriptor或空响应?大概率是desp里含未转义的换行或特殊字符,改用printf或先urlencode
Server酱本身不保活、不重试,一次 curl 失败就没了。真要高可靠,得自己加重试逻辑或换企业微信/钉钉机器人——但对大多数小站点,按上面配好 trap + 绝对路径 + curl -s -m 10 就够用了。










