1

I am writing a shell script to rotate a log file based on size leveraging the logrotate.conf utility.

#!/bin/bash 
FILENAME=/xyz/console.log  

    while :
    do  
        FILESIZE=$(du -h "$FILENAME")

        ####FILESIZE=$(stat -c%s "$FILENAME")

        if [[ $FILESIZE > 10K ]];
        then
            echo "$FILENAME is too large = $FILESIZE"
            echo "$(date ) is here"
            cd "/etc"
            $sudo logrotate -f logrotate.conf
            echo "$ Newer version of log file is created"
        else
            echo "Log limit is not reached"
        fi
    sleep 60s

done

exit 0

It is not printing else block ,even when the size is less than 10K. In all cases, it is executing the if block and rotating the logs even at 4.0K. Only when the log file is of zero bytes it is printing else part i.e.:

Log limit is not reached

1
  • Why not use stat or du (without -h)? The problem is that du will bring the file name too, unless you use cut -f 1. The ideal is to get the value in bytes and compare. Commented Dec 29, 2017 at 7:22

2 Answers 2

3

The problem is that [[ > ]] is doing a string comparison (essentially, alphabetical order) rather than numeric comparison. So, for example, [[ 9 > 10 ]] is true, because the character "9" comes after "1" in ASCII sorting order. But switching to numeric comparisons (with (( > )) or [[ -gt ]]) won't work either, because the "numbers" you're comparing have unit suffixes ("B" for byte, "K" for kilobyte, etc, so 500B is less than 1K) and the output from du also includes the filename, which'd need to be striped before comparing.

This is much too much work. Just use stat to get a pure numeric result, and do numeric comparison on that. Oh, and you should stick to lower- or mixed-case variable names, to avoid accidentally using one of the ones that has special meaning to the shell (e.g. PATH):

...
filesize=$(stat -f %z "$filename")
if (( filesize > 10240 )); then
...
Sign up to request clarification or add additional context in comments.

2 Comments

I have tried various options as suggested and modified the code as while : do FILESIZE=$(du "$FILENAME") #FILESIZE=$(stat -c%s "$FILENAME") #FILESIZE=$( du -b "$FILENAME" | cut -f1) if (( $FILESIZE > 1000000 )); then echo "$FILENAME is too large = $FILESIZE" echo "$(date ) is here" cd "/etc" $sudo logrotate -f logrotate.conf echo "$ Newer version of log file is created" else echo "Log limit is not reached" fi sleep 60s the log file in question is 96185 bytes..still getting rotated
@SoumikBhattacharya Did you try the stat command I recommended? Also, have your script print the value of FILESIZE before checking it, so you can see what's actually happening.
1

You are using string comparision. For example, if the file size is 2K, 2K > 10K is true, because 2 comes alphabetically after 10.

Easiest solution would be to drop the -h option - which doesn't make much sense anyway, if you want to process the result further - and then use numerical comparision,

if (( FILESIZE > 10 ))
then

fi

2 Comments

I have tried various options as suggested and modified the code as while : do FILESIZE=$(du "$FILENAME") #FILESIZE=$(stat -c%s "$FILENAME") #FILESIZE=$( du -b "$FILENAME" | cut -f1) if (( $FILESIZE > 1000000 )); then echo "$FILENAME is too large = $FILESIZE" echo "$(date ) is here" cd "/etc" $sudo logrotate -f logrotate.conf echo "$ Newer version of log file is created" else echo "Log limit is not reached" fi sleep 60s the log file in question is 96185 bytes..still getting rotated
Post your modified code. Also, show the value of FILESIZE.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.