#!/usr/bin/perl # watchdir: # This script prints info about changes to the directory specified # as a command-line argument. If no command-line arg is supplied, # it watches the current directory. # Cameron Hayne (macdev@hayne.net) December 2005 use strict; use warnings; # global variables my $interval = 10; # time (in seconds) between checks # If no command-line argument, use the current directory my $dirname = scalar(@ARGV) >= 1 ? $ARGV[0]: "."; die "$dirname is not a directory\n" unless -d $dirname; sub get_dir_entries($) { my ($dirname) = @_; my %entries = (); opendir(DIR, $dirname) or die "can't opendir $dirname: $!\n"; while (defined(my $filename = readdir(DIR))) { next if $filename =~ /^\.\.?$/; # skip . and .. $entries{$filename} = 1; } closedir(DIR); return \%entries; } sub diff_hash_keys($$) { my ($ref_hashA, $ref_hashB) = @_; my %hashA = %$ref_hashA; my %hashB = %$ref_hashB; my @A_not_B = (); my @B_not_A = (); foreach (keys %hashA) { push(@A_not_B, $_) unless exists $hashB{$_}; } foreach (keys %hashB) { push(@B_not_A, $_) unless exists $hashA{$_}; } return (\@A_not_B, \@B_not_A); } MAIN { $| = 1; # enable autoflushing of output so this works better when piped my $prev = undef; while (1) { my $date = localtime(); my $curr = get_dir_entries($dirname); if (defined($prev)) { my ($added, $removed) = diff_hash_keys($curr, $prev); foreach (sort @$added) { print "$date: Added file $_\n"; } foreach (sort @$removed) { print "$date: Removed file $_\n"; } if (@$added || @$removed) { print "\a"; # make a beep } } $prev = $curr; sleep $interval; } }