Permission denied 是 logrotate 以 root 身份运行时在三处权限缺失:/etc/logrotate.d/nginx 配置文件不可读、/var/log/nginx/ 目录不可写、/bin/gzip 命令不可执行;需用 logrotate -d 检查是否加载配置、确认文件顺序与路径权限。

logrotate 报 Permission denied 是谁没权限?
不是脚本本身没执行权,而是 logrotate 以 root 身份运行时,访问某些路径或调用命令失败了。常见位置有三处:/etc/logrotate.d/nginx 配置文件不可读、/var/log/nginx/ 目录不可写、/bin/gzip 命令不可执行。先别急着 chmod 777,得定位具体是哪一环卡住。
- 检查配置文件权限:
ls -l /etc/logrotate.d/nginx,必须至少是-rw-r--r--(644),且属主为 root;若权限是 600 但组/其他无读权,logrotate 会静默跳过该文件 - 确认日志目录可写:
ls -ld /var/log/nginx,输出中要有w(如drwxr-xr-x),注意 setgid 或 ACL 可能覆盖默认行为 - 验证 gzip 是否可用:
which gzip→ls -l $(which gzip),确保它有x权限,且所在目录(如/bin)对 root 可进入(x)
logrotate -d 输出里看不到 compress 指令?
说明你的配置根本没被加载,而不是压缩失败。logrotate 按字母顺序读取 /etc/logrotate.d/ 下的文件,如果存在 nginx-old、00-nginx 或其他命名靠前的同名规则,你的 nginx 文件可能被跳过。
- 运行
logrotate -d /etc/logrotate.conf,重点看输出中是否列出你的日志路径(如/var/log/nginx/*.log)和compress动作 - 检查是否有冲突文件:
ls -1 /etc/logrotate.d/ | grep -E '^(nginx|00|old)' - 重命名你的配置为
zzz-nginx强制排到最后,再试一次 debug
postrotate 里 kill -USR1 失败也报权限不足?
不是信号发不出去,而是 logrotate 找不到 pid 文件,或 nginx 进程不是 root 启动的。错误常表现为 Permission denied 或 No such process,但真实原因是上下文不匹配。
- 确认 pid 文件路径正确:
cat /etc/nginx/nginx.conf | grep pid,常见是/var/run/nginx.pid或/run/nginx.pid - 检查 pid 文件权限:
ls -l $(cat /var/run/nginx.pid 2>/dev/null),若属主不是 root 或不可读,logrotate 无法解析进程号 - 如果 nginx 由
www-data或nginx用户启动,postrotate 中要用su -c "nginx -s reopen" -s /bin/sh www-data切换用户再发信号
为什么手动执行 logrotate -f 没问题,cron 里就失败?
因为 cron 环境变量极简,PATH 往往不含 /usr/sbin,而 logrotate 二进制通常在那儿。你手动运行时 PATH 完整,cron 里却找不到命令或依赖工具(比如 gzip、kill)。
- 在
/etc/cron.daily/logrotate开头加一行:PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin - 或者直接在 logrotate 配置里写绝对路径:
postrotate /usr/sbin/nginx -s reopen >/dev/null 2>&1 - 更稳妥的做法:用
logrotate -f /etc/logrotate.d/nginx 2>&1 | tee /tmp/logrotate-debug.log模拟 cron 环境抓输出
真正难排查的永远不是“哪个权限不对”,而是“logrotate 在什么身份、什么环境、读了哪份配置、调了哪个命令”。debug 模式输出里的每一行,都是它实际走过的路径,别跳读。

















