7

I would like to send an email when a file reach a certain size limit.

The only way I thought of doing this is by doing a cronjob which will check the file size and send the email if the file is bigger than the desired size.

However, it seems like a bad solution for me to add a cronjob which would check ,for example every 15-30 min, the size of a file?

I was wondering if there is a better way of doing this to automatically detect when the file is appended some text (event?) so I could then check the size and do the desired treatment.

8

I can conceive of 2 approaches to do this. You can either use a while loop which would run a "stat" command at some set frequency, performing a check to see if the file's size has exceeded your desired size. If it has, then send an email. This method is OK but can be a bit inefficient since it's going to run the "stat" command irregardless if there was an event on the file or not, at the set time frequency.

The other method would involve using file system events that you can subscribe watchers to using the command inotifywatch.

Method #1 - Every X seconds example

If you put the following into a script, say notify.bash:

#!/bin/bash

file="afile"
maxsize=100    # 100 kilobytes

while true; do
    actualsize=$(du -k "$file" | cut -f1)
    if [ $actualsize -ge $maxsize ]; then
        echo size is over $maxsize kilobytes
        .... send email ....
        exit
    else
        echo size is under $maxsize kilobytes
    fi

    sleep 1800 # in seconds = 30 minutes
done

Then run it, it will report on any access to the file, if that access results in the file's size exceeding your minimum size, it will trigger an email to be sent and exit. Otherwise, it will report the current size and continue watching the file.

Method #2 - Only check on accesses example

The more efficient method would be to only check the file when there are actual accesses. The types of accesses can vary, for this example I'm illustrating how to watch for just file accesses, but your could watch only on other events, such as the file being closed. Again we'll name this file, notify.bash:

#!/bin/bash

file=afile
maxsize=100 # 100 kilobytes

while inotifywait -e access "$file"; do
    actualsize=$(du -k "$file" | cut -f1)
    if [ $actualsize -ge $maxsize ]; then
        echo size is over $maxsize kilobytes
        .... send email ....
        exit    
    else
        echo size is under $maxsize kilobytes
    fi
done

Running this script would result in the following output:

$ ./notify.bash 
Setting up watches.
Watches established.

Generating some activity on the file, the file now reports it's size as follows:

$ seq 100000 > afile
$ du -k afile 
576 afile

The output of our notification script:

afile ACCESS 
size is over 100 kilobytes

At which point it would exit.

Sending email

To perform this activity you can simply do something like this within the script:

subject="size exceeded on file $file"
emailAddr="user@somedom.com"
mailCmd="mail -s \"$subject\" \"$emailAddrs\""
( echo ""; echo "DATE: $(date)"; ) | eval mail -s "$subject" \"$emailAddr\"

Considerations

The second method as it is will work in most situations. One where it will not is if the file is already exceeding the $maxsize when the script is invoked, and there are no further events on the file of type access. This can be remedied with either an additional check performed in the script when it's invoked or by expanding the events that inotifywatch acts on.

References

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.