質問

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! :)

役に立ちましたか?

解決

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
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top