Recursive rsync backup script
From Admin-SIG
[edit]
coreBackup.pl
#!/usr/bin/perl -w
#
# Use rsync (and a remote rsyncd) to back up the IMPORTANT stuff on a system.
# Create a file /.backupList containing directories to be backed up.
#
# If that directory does NOT have a .backupList file, the whole
# folder will be backed up. (Except for exceptions listed in
# .backupExclude)
#
# If it does have a .backupList file, only the files/directories
# in that list will be backed up.
#
# Each directory to be backed up will be checked for another .backupList file
sub rsyncCmd{
local ($dir,$dest) = @_;
local $cmd = "rsync -arcz --password-file=/etc/rsync.password";
$cmd .= " \"--exclude-from=$dir/.backupExclude\"" if (-f "$dir/.backupExclude");
$cmd .= " \"$dir\" \"$dest\"";
return($cmd);
}
($#ARGV == 1) or die "\nUsage: $0 host::volume directory
where host is the remote rsyncd host, and
volume is the backup volume enabled on that host.
directory is the local directory to rsync.
Note that the directory CONTAINING directory must exist
on the remote backup server, or the command will fail.\n\n";
#$rsyncFmt .= $ARGV[0]; # add on host::volume spec.
$dest = $ARGV[0]; # host::volume spec.
($parent, $leaf, $dir) = &splitPath($ARGV[1]);
$_ = $leaf; # supress warning.
#print "$parent!$leaf!$dir\n";
$listFile = "$dir/.backupList";
if (!(-f $listFile))
{ # backup this folder recursively
$cmd = &rsyncCmd($dir,$dest . $parent);
system("date");
print "$cmd\n";
exec($cmd);
}
# process .backupList
@list = &loadList($listFile);
foreach $item (@list)
{
local $a = "$dir/$item";
if (-f $a)
{ # just a file, back it up
local $t = $dest;
$t .= "/$parent" if ($parent ne "");
#$cmd = &rsyncCmd($a,$dest . );
$cmd = &rsyncCmd($a,$t);
print "$cmd\n";
system($cmd);
}
else
{ # backup the folder, recursive call
$cmd = sprintf("$0 %s \"%s\"",$ARGV[0],$a);
print "$cmd\n";
system($cmd);
}
}
#---------------------------------------------------------
sub splitPath {
local ($dir) = @_;
$_ = $dir;
s/^\s+//;
s/\s+$//;
return("","","") if ($_ eq "/");
chomp;
#print "dir=$dir\n";
local @p = split(/\//,$dir);
#foreach(@p){print "\"$_\" ";}print "\n";
return(join("/",@p[0..$#p-1]),$p[$#p],$dir);
}
# process comments and blank lines from list
sub loadList{
local ($fNam) = @_;
open(F,"<$fNam") or return;
local @list;
while(<F>)
{
chomp;
s/#.*$//;
s/^\s+//;
s/\s+$//;
@list = (@list,$_) if (m/.+/);
}
close(F);
return(@list);
}

