LinuxProNews Home Page About iEntry Article Archive News WebProWorld Forums Jayde iEntry Contact Advertise Downloads iEntry
^ click above ^
12.05.03

Monitoring File or Directory Changes

By A.P. Lawrence

Many modern systems provide a way to watch a directory for events (new files, reading the directory, modification of a file in the directory, etc.). This facility can be done in various ways, from providing hooks in the filesystem code itself to something that watches for inode changes. Linux and BSD have several possibilities in that regard, including dnotify, changedfiles, and watch.

Mac OS X has FileMonitor (shareware), and it's certainly possible that some of the BSD tools might compile on OS X. But what do you do when there is no support in the OS?

Brute Force
Typically you are interested in new files in a particular directory. You can do something like this:

touch /tmp/testdirb.$$
while true
do
ls /testdir > /tmp/testdira.$$
diff /tmp/testdira.$$ /tmp/testdirb.$$ || echo "changed"
cp /tmp/testdira.$$ /tmp/testdirb.$$
sleep 300
done



Get WebSiteNotes Newsletter Free -
">Click Here


If you were looking for a particular file to change, you'd use "ls -l", and if your interest was in if the file was being used or executed, "ls -lut" would give you that. This example justs echoes when something changes, but you would more likely call some other script that did more testing. One obvious issue that comes up if a file has been created is waiting for the creating program to have finished up: lsof or fuser can help you with that.

But this is pretty crude. Sometimes crude is fine, but if you need to know more often, there's a fair amount of overhead in this that you really don't need.

Stat

Linux systems have a command line "stat" that can make checking changes a little less intensive. "stat -t testdir" looks something like this:

testdir 4096 8 41ed 5001 5001 303 82022 2 2b 1d 1070127877 1070128608 1070128608

which is everything you want to know about the file or directory for this purpose. Security Enhanced Linux versions add another field which we need to strip out for our purposes here:

OLD=`stat -t testdir`
# OLD=`stat -t testdir | sed 's/[0-9][0-9]*$//'` # if SE linux stat
while true
do
NEW=`stat -t testdir`
# NEW=`stat -t testdir | sed 's/[0-9][0-9]*$//'` if SE linux stat
[ "$NEW" == "$OLD" ] || echo "changed!"
sleep 3
done


You could get fancier by splitting out the fields into separate variables. That isn't a lot of fun at the shell level, so we'll move up a notch.


Perl or C

From Perl or C (and of course many other languages), you can get access to the stat information a bit more easily. Here's a simple Perl example like those already given:
#!/usr/bin/perl
@info=stat("testdir") or die "Can't stat testdir $!";
while (1) {
@newinfo=stat("testdir") or die "Can't stat testdir $!";
@what=qw(Device Inum Mode Links Owner Group Rdev Size Atime Mtime Ctime 
    PBlock Blocks);
$x=0;
while ($info[$x]) {
  system("/bin/echo $what[$x] $info[$x] $newinfo[$x]") if ($info[$x] 
    ne $newinfo[$x]);
  $x++;
}
@info=@newinfo;
sleep 1;
}

About the Author:
A.P. Lawrence provides SCO Unix and Linux consulting services http://www.pcunix.com


Read this newsletter at: http://www.linuxpronews.com/2003/1205.html

Free Newsletters
Part of the iEntry Network
over 4 million subscribers
LinuxProNews
FlashNewz
HiTechEdge


Send me relevant info on products and services.








From the Forum:
Linux for everything?
Ok here is my question. We are changing our computers over and due to a virus from time to time on windows and the fact that most people here use Linux a lot of people here want to do away with windows on all the computers. ...

Click here







-- LinuxProNews is an iEntry, Inc. publication --
2003 iEntry, Inc.  All Rights Reserved  Privacy Policy  Legal

archives | advertising info | news headlines | free newsletters | comments/feedback | submit article




To unsubscribe from these mailings reply to this message with "unsubscribe 200" in the subject or ">click here.