--
--PART-BOUNDARY=.11030911220316.ZM11510.localdomain
Content-Type: text/plain; charset=us-ascii
The recent scp discussion reminded me of a script (attached) that I
wrote a while back. I call it constant_sync and I use it when I want
to develop code on one machine that (nearly instantly) gets mirrored
to another. (I don't like doing any serious editing on remote machines.)
``constant_sync'' uses rsync, and it is made to use ssh (instead of
rsh) as the transport by setting RSYNC_RSH to ssh. As noted in the
script it's a good idea to use ssh-agent to avoid having to constantly
log in.
``constant_sync'' also uses ``fam'' the "file alteration monitor" to
detect changes to files. It'll be necessary to install the perl
module SGI::FAM (and make sure that you have "fam" running) if you
want to use this script.
Kevin
--PART-BOUNDARY=.11030911220316.ZM11510.localdomain
Content-Description: Text
Content-Type: text/plain ; name="constant_sync" ; charset=us-ascii
Content-Disposition: attachment ; filename="constant_sync"
X-Zm-Content-Name: constant_sync
#!/usr/bin/perl -w
use SGI::FAM;
use File::PathConvert qw(realpath abs2rel splitpath);
if (@ARGV != 2) {
die "Usage: $0 <src> <dest>\n";
}
my ($src, $dest) = @ARGV;
if (! -r $src) {
die "$src does not exist!\n";
}
my $src_prefix;
if (-d $src) {
chdir $src or die "Can't chdir to $src: $!";
$src = '.';
$src_prefix = realpath($src);
}
elsif ($src =~ m#./#) {
($src_prefix, $src) = ($src =~ m#^(.*)/([^/]*)$#);
chdir $src_prefix or die "Can't chdir to $src_prefix: $!";
$src_prefix = realpath($src_prefix);
-r $src or die "Can't locate $src!\n";
}
# Use rsync to copy $src to $dst. It's best to have ssh_agent running
# to avoid constantly having to log in...
rsync($src, $dest);
my $fam = new SGI::FAM;
my $file_list_length_limit = 4096 - length($dest) - 30;
my @pending_dirs_to_monitor;
my @pending_files_to_copy;
$fam->monitor($src);
while (1) {
if (!$fam->pending) {
if (@pending_dirs_to_monitor) {
my $mfile;
$mfile = shift @pending_dirs_to_monitor;
print "Asking for monitor on $mfile\n";
$fam->monitor($mfile);
}
print "DEBUG (before duplicate removal):", join ',', @pending_files_to_copy, "\n";
# Sometimes - though I don't know why - a name will appear
# multiple times. Eliminate the duplicates.
@pending_files_to_copy = sort @pending_files_to_copy;
for (my $i = 1; $i < @pending_files_to_copy;) {
if ($pending_files_to_copy[$i - 1] eq $pending_files_to_copy[$i]) {
splice @pending_files_to_copy, $i, 1, ();
}
else {
$i++;
}
}
print "DEBUG (after duplicate removal):", join(',', @pending_files_to_copy), "\n";
# Sometimes a CVS operation will create a temporary file that
# disappears by the time we get here.
@pending_files_to_copy = grep { -r } @pending_files_to_copy;
while (@pending_files_to_copy) {
my $file_list = '';
# Be careful not to try to copy too many files at a time.
while (@pending_files_to_copy
&& length($file_list) + length($pending_files_to_copy[0]) + 1
< $file_list_length_limit) {
$file_list .= ' ' . shift(@pending_files_to_copy);
}
rsync($file_list, $dest);
}
}
my $event = $fam->next_event; # Blocks
my $type = $event->type;
my $dirname = realpath($fam->which($event));
my $filename = $event->filename;
my $fullname = ($filename =~ m#/#) ? $filename : "$dirname/$filename";
#print "$fullname: $type\n";
if (($type eq 'change' && ! -d $fullname) || $type eq 'create') {
#rsync($src_path, $dest_path);
#print "rsync $src_path $dest_path\n";
push @pending_files_to_copy, abs2rel($fullname, $src_prefix);
}
if (($type eq 'create' || $type eq 'exist') && -d $fullname
&& ! $fam->monitored($fullname)) {
push @pending_dirs_to_monitor, $fullname;
}
}
sub rsync {
my ($src, $dest) = @_;
$ENV{RSYNC_RSH} = "ssh";
print "rsync -CRavuz $src $dest\n";
$status = system("rsync -CRavuz $src $dest");
if ($status == -1) {
die "Couldn't start rsync: $!\n";
}
$status /= 256;
if ($status != 0) {
warn "Warning: status value from rsync was $status\n";
}
}
--PART-BOUNDARY=.11030911220316.ZM11510.localdomain--