Fix: logrotate causes cron emails with “gzip: stdin: file size changed while zipping”

If you are like me, you are notified of both email and syslog errors from your Linux hosts. If you aren’t, you don’t know what’s wrong with your computers. But if you are, you sometimes have to deal with noise, like this totally useless message:

From: Anacron 
To: root@host.example.com
Subject: Anacron job 'cron.daily' on host

/etc/cron.daily/logrotate:
gzip: stdin: file size changed while zipping

This is caused by a logrotate definition using “compress” without “delaycompress”. The error message is especially unhelpful because it doesn’t contain the filename causing the problem, due to the way logrotate invokes gzip as a pipeline.


To fix it, add “delaycompress” to all logrotate definitions using “compress”:

cd /etc/logrotate.d
sed -i '/^\(\s*\)compress/a\\tdelaycompress' $(grep -L delaycompress $(grep -lE '^[^#]*\bcompress\b' *))

This is a set of three nested commands using the $() operator of bash (better than `` for nesting). You should read them from right to left. Here is what they do:

  1. grep -lE '^[^#]*\bcompress\b' * – list all files with exactly the keyword “compress”
  2. grep -L delaycompress $RESULTS_FROM_1 – for all files in $RESULTS_FROM_1, list files not containing “delaycompress”
  3. sed -i '/^\(\s*\)compress/a\\tdelaycompress' $RESULTS_FROM_2 – for all files in $RESULTS_FROM_2, append the line “delaycompress” after the line “compress”.

In case you prefer to edit these files by hand, you can list them with:
grep -L delaycompress $(grep -lE '^[^#]*\bcompress' *)

Warning: this has some bugs. It assumes tabs as indents, while some logrotate definitions may use space (doesn’t matter, but humans might care). And if you have files containing entries both with and without delaycompress, it won’t fix those. For that, you need a more complicated program. I’ve stopped short of that, since the above fixes my need.

Tags: , ,

  1. ladiko’s avatar

    Same approach, but might be easier to read left to right:

    “`
    grep compress -l /etc/logrotate.d/* | xargs grep -L delaycompress | sudo xargs sed -i ‘/compress/a \\tdelaycompress’
    “`

    grep for all files which have the word compress, hand tgem over via xargs and grep for the files not containing delaycompress, hand them over to xargs and append delaycompress after each line containing compress.

    Reply

Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.