Ognjen Galić
Ognjen Galić

Reputation: 2742

Watching folder for changes - bash efficiency

I've got this:

#!/bin/bash

while :
do

SUM=$(tree | md5sum)

if [ "$SUMOLD" != "$SUM" ]; then

# do something here

SUMOLD=$SUM
sleep 1

fi

done

Which works just fine. But, the problem is that it consumes 50% of the CPU, a Core2 Duo T8300. Why is that? How to improve the efficiency?

Upvotes: 0

Views: 80

Answers (3)

that other guy
that other guy

Reputation: 123470

While a OS specific solution like inotify would be better, you can dramatically improve your script by moving the sleep out of the if statement:

#!/bin/bash

while :
do
  SUM=$(tree | md5sum)    
  if [ "$SUMOLD" != "$SUM" ]; then
    # do something here    
    SUMOLD=$SUM
    # move sleep from here
  fi
  sleep 1 # to here
done

CPU usage should drop dramatically now that you're always checking once per second, instead of as often as possible when there are no changes. You can also replace tree with find, and sleep for longer between each check.

Upvotes: 1

John Kugelman
John Kugelman

Reputation: 361615

This is a job for inotifywait. inotify is Linux's event-based system for monitoring files and directories for changes. Goodbye polling loops!

NAME
inotifywait - wait for changes to files using inotify

SYNOPSIS

inotifywait [-hcmrq] [-e <event> ] [-t <seconds> ] [--format <fmt> ]
            [--timefmt <fmt> ] <file> [ ... ]

DESCRIPTION
inotifywait efficiently waits for changes to files using Linux's inotify(7) interface. It is suitable for waiting for changes to files from shell scripts. It can either exit once an event occurs, or continually execute and output events as they occur.

Here's how you could write a simple loop which detects whenever files are added, modified, or deleted from a directory:

inotifywait -mq /dir | while read event; do
    echo "something happened in /dir: $event"
done

Take a look at the man page for more options. If you only care about modifications and want to ignore files simply being read, you could use -e to limit the types of events.

Upvotes: 5

Juan Lago
Juan Lago

Reputation: 1048

The reason is that the script is continuously running even when the command sleep is called. My recommendation is to launch your script using the "inotifywait" or the "watch" (Alternative solution) command and avoid to use the while loop.

See: http://linux.die.net/man/1/watch

An example taken from the MAN pages:

To watch the contents of a directory change, you could use

watch -d ls -l

Watch is going to launch your script periodically but without continuously execute your script.

Upvotes: -1

Related Questions