Domanda

Is it possible to see which files have been changed whenever an change-event is called using: https://metacpan.org/pod/Mac::FSEvents ?

Thanks a lot! :)

È stato utile?

Soluzione

File System Events API was designed to mirror large tree of files changes, if you want to mirror particular file changes you might be better of with IO::KQueue. The perl binding is missing a few constant for event flags, but you can obtain these from File System Events Programming Guide.

This script should get you started, it prints out any file events in '/path'

#!/usr/bin/perl
use strict;
use warnings;

use IO::Select    qw[];
use Mac::FSEvents qw[FILE_EVENTS];

my $fse = Mac::FSEvents->new({
    path  => '/path',
    flags => FILE_EVENTS
});

my $select = IO::Select->new($fse->watch);

# http://developer.apple.com/library/mac/#documentation/Darwin/Reference/FSEvents_Ref/FSEvents_h/index.html#//apple_ref/c/tag/FSEventStreamEventFlags
my %names = reverse (
    kFSEventStreamEventFlagNone              => 0x00000000,
    kFSEventStreamEventFlagMustScanSubDirs   => 0x00000001,
    kFSEventStreamEventFlagUserDropped       => 0x00000002,
    kFSEventStreamEventFlagKernelDropped     => 0x00000004,
    kFSEventStreamEventFlagEventIdsWrapped   => 0x00000008,
    kFSEventStreamEventFlagHistoryDone       => 0x00000010,
    kFSEventStreamEventFlagRootChanged       => 0x00000020,
    kFSEventStreamEventFlagMount             => 0x00000040,
    kFSEventStreamEventFlagUnmount           => 0x00000080,
    kFSEventStreamEventFlagItemCreated       => 0x00000100,
    kFSEventStreamEventFlagItemRemoved       => 0x00000200,
    kFSEventStreamEventFlagItemInodeMetaMod  => 0x00000400,
    kFSEventStreamEventFlagItemRenamed       => 0x00000800,
    kFSEventStreamEventFlagItemModified      => 0x00001000,
    kFSEventStreamEventFlagItemFinderInfoMod => 0x00002000,
    kFSEventStreamEventFlagItemChangeOwner   => 0x00004000,
    kFSEventStreamEventFlagItemXattrMod      => 0x00008000,
    kFSEventStreamEventFlagItemIsFile        => 0x00010000,
    kFSEventStreamEventFlagItemIsDir         => 0x00020000,
    kFSEventStreamEventFlagItemIsSymlink     => 0x00040000
);

use constant kFSEventStreamEventFlagItemIsFile => 0x00010000;

while ($select->can_read) {
    for my $event ($fse->read_events) {
        my $flags = $event->flags;
        my @names;

        next unless $flags & kFSEventStreamEventFlagItemIsFile;

        while ((my $flag = $flags & -$flags) != 0) {
            push @names, $names{$flag} || sprintf '0x%.8X';
            $flags &= ~$flag;
        }

        printf qq['%s': %s\n], $event->path, join ' | ', @names;
    }
}
$fse->stop;

Example events:

$ echo foo > foo.txt
'/path/foo.txt': kFSEventStreamEventFlagItemCreated | kFSEventStreamEventFlagItemModified | kFSEventStreamEventFlagItemIsFile

$ touch foo.txt
'/path/foo.txt': kFSEventStreamEventFlagItemInodeMetaMod | kFSEventStreamEventFlagItemIsFile

$ echo foo >> foo.txt
'/path/foo.txt': kFSEventStreamEventFlagItemModified | kFSEventStreamEventFlagItemIsFile

$ mv foo.txt bar.txt
'/path/foo.txt': kFSEventStreamEventFlagItemRenamed | kFSEventStreamEventFlagItemIsFile
'/path/bar.txt': kFSEventStreamEventFlagItemRenamed | kFSEventStreamEventFlagItemIsFile

$ rm bar.txt
'/path/bar.txt': kFSEventStreamEventFlagItemRemoved | kFSEventStreamEventFlagItemIsFile
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top