#!/usr/bin/perl # atchange - monitor a file and run a command when it changes # http://www.cs.indiana.edu/~kinzler/home.html#other # by Jeff Haemer # and a tip o' the hat to Tom Schneider # who wrote the original version as a shell script # version = 2.03 of atchange 1997 Jan 9 # delay time is 0.25 seconds # modified 1998 Aug 7 by kinzler@cs.indiana.edu # made Perl4 compatible, changed usage string # For current version and other information about this program, see: # http://www-lmmb.ncifcrf.gov/~toms/atchange.html # Tom Schneider # National Cancer Institute # Laboratory of Mathematical Biology # Frederick, Maryland 21702-1201 # toms@ncifcrf.gov # http://www-lmmb.ncifcrf.gov/~toms/ $0 =~ s(.*/)(); # basename $usage = "usage: $0 [ filename cmd | command_file ]"; @ARGV || die $usage; # check for proper invocation $shell = $ENV{"SHELL"} ? $ENV{"SHELL"} : "/bin/sh"; open(SHELL, "|$shell") || die "Can't pipe to $shell: $!"; select(SHELL); $| = 1; if (@ARGV > 1) { # it's a file and a command $file = shift; # peel off the filename $cmd{$file} = join(" ", @ARGV) . "\n"; # and the command $old{$file} = (stat($file))[9]; # mod time. } else { # it's a program open(PGM, shift) || die "Can't open $_: $!"; $/ = ""; # paragraph mode while() { # first read the program s/#.*\n/\n/g; ($file, $cmd) = /(\S*)\s+([^\000]+)/; $cmd{$file} = $cmd; unless ($file) { print $cmd{$file}; next; } if ($file && ! $cmd{$file}) { warn "odd line"; next; }; $old{$file} = (stat($file))[9]; # mod time. } } while(1) { # sleep 1; # wait a second, then select(undef, undef, undef, 0.25); # wait a quarter second, then foreach (keys %cmd) { # rip through the whole list &atchange($_); } } close(SHELL); sub atchange { # if $file has changed, do $cmd{$file} local($file) = @_; local($new); $new = (stat($file))[9]; return 0 if ($old{$file} == $new); while (1) { # wait until it stops changing $old{$file} = $new; sleep 1; $new = (stat($file))[9]; if ($old{$file} == $new) { print $cmd{$file}; return 1; } } }