logrotate 无法直接发送企业微信通知,需通过 shell 脚本中转:编写 /usr/local/bin/wechat-notify.sh 接收 $1(轮转后文件路径),校验文件存在后用 curl 向企业微信 webhook 发送 json 消息;logrotate 配置中以绝对路径调用该脚本并传参 "$1",确保 root 可执行且 curl 已安装。

logrotate 里不能直接发微信通知,得靠 shell 脚本中转
logrotate 本身不支持 HTTP 请求或消息推送,postrotate 阶段只能执行本地命令。所以必须写一个独立的 shell 脚本(比如 /usr/local/bin/wechat-notify.sh),在 logrotate 完成轮转后调用它,由它拼好 JSON、用 curl 推送到企业微信机器人 webhook 地址。
怎么写能发消息的 shell 脚本
脚本要能接收 logrotate 传来的日志路径(可选),并判断是否真发生了轮转(避免空跑)。关键点:
- 必须用
#!/bin/bash开头,且赋予可执行权限:chmod +x /usr/local/bin/wechat-notify.sh - 企业微信 webhook 地址要硬编码或从环境变量读取,别塞进 logrotate 配置里(易泄露)
- 用
curl -X POST -H 'Content-Type: application/json' -d '{...}' $WEBHOOK_URL发送,JSON 中text字段用$(date +%F\ %T)和$1(即轮转后的文件名)拼内容 - 加
if [ -f "$1" ]; then ... fi判断文件是否存在,防止postrotate在没真正轮转时也触发
示例片段:
解析微信公众号文章,提取标题、作者、正文、图片等信息。用户发送链接(mp.weixin.qq.com)时触发,自动提取内容并可保存至飞书表格。
#!/bin/bash
WEBHOOK="https://qyapi.weixin.qq.com/xxx"
[ -z "$1" ] && exit 0
[ ! -f "$1" ] && exit 0
curl -s -X POST -H 'Content-Type: application/json' \
-d "{\"msgtype\": \"text\", \"text\": {\"content\": \"[logrotate] $(basename $1) rotated at $(date +'%F %T')\"}}" \
"$WEBHOOK" > /dev/null 2>&1
logrotate 配置里怎么安全调用
postrotate 必须用绝对路径调用脚本,并显式传入 $1(logrotate 自动设为当前匹配的日志文件路径)。别用 sh /path/to/script,而要用 /usr/local/bin/wechat-notify.sh "$1",否则 $1 会丢失。
- 确保 logrotate 运行用户(通常是
root)有执行该脚本的权限 - 如果脚本依赖
curl,确认系统已安装:which curl,否则postrotate静默失败 - 不要在
postrotate里写多行命令——全塞进一行或封装到脚本里,logrotate 对换行和分号很敏感 - 测试时先手动运行:
logrotate -d /etc/logrotate.d/myapp(-d 查看调试输出,确认postrotate是否被触发)
为什么消息总收不到?几个硬坑
企业微信机器人限制极严,出错不会返回明显提示,容易卡在无声失败:
- webhook URL 末尾多了空格或换行(复制时常见),用
echo "$WEBHOOK" | hexdump -C检查 - JSON 格式错误:单引号不能替代双引号,
"content": "xxx"里的双引号必须是 ASCII 字符,中文引号会 400 - 消息频率超限:同一个机器人 24 小时最多 200 条,测试时别反复 reload
- logrotate 用户无网络权限:某些安全加固系统禁止
root外的用户访问外网,但 logrotate 默认以 root 运行,这点一般没问题;真正要查的是脚本里curl是否被 SELinux 或 firewalld 拦住
最稳妥的验证方式:手动执行一遍脚本,把 curl 行末尾的 > /dev/null 2>&1 去掉,看终端是否返回 {"errcode":0,"errmsg":"ok"}。










