[Nelug] Backup using rsync

Martin Ward martin at gkc.org.uk
Fri May 19 18:22:15 UTC 2006


Last meeting we were discussing backups using rsync. Here's one of the scripts
I use to do this. It backs up /home/martin to /home/backup/martin
with historical copies in martin.1 martin.2 etc. where unchanged files in
two directories are hard linked to the same file.

#! /usr/bin/perl
# Incremental backup of /home to external drive

# (1) Delete oldest backup and shift others up
# (2) Create home dir and copy .ssh subdir (so that ssh still works!)
# (3) Use rsync to pull across any changed files, linking to previous backup

use strict;
use warnings;

sub mysystem($);

my $dir = "/home/backup";
my $file = "martin";
my $date_file = ".last_increment";
my $new_date = ".date";
my $levels = 7;

(my $myname = $0) =~ s|(.*/)*||;        # strip path component from name
my $hostname = `hostname`;
chomp($hostname);
$hostname =~ s/\..*//;

chdir $dir or die "Can't chdir $dir: $!\n";
die "Can't find $date_file: $!" unless -M $date_file;

my $AGE_OF_last_increment = -M $date_file;

print "Last increment was $AGE_OF_last_increment days ago.\n";

if ($AGE_OF_last_increment > 0.5) {
  open(DATE, ">$new_date") or die "Can't write $new_date: $!\n";
  my $date = localtime(time);
  print DATE "$date\n";
  close(DATE);
  rename $new_date, $date_file;
  if (-d "$file.$levels") {
    print "Deleting $file.$levels...\n";
    mysystem "rm -rf $file.$levels";
  }
  foreach my $ext (reverse(1..$levels-1)) {
    next unless (-d "$file.$ext");
    my $new = $ext + 1;
    rename("$file.$ext", "$file.$new")
      or die "Rename $file.$ext, $file.new failed: $!\n";
    print "$file.$ext --> $file.$new\n";
  }
  rename($file, "$file.1") or die "Rename $file, $file.1 failed: $!\n";
  print "Creating $file...\n";
  mkdir $file;
}

mysystem qq[rsync -av --delete]
           . qq[ --link-dest=$dir/$file.1/]
           . qq[ /home/$file/ $dir/$file/];

chdir "/"; # so we are no longer using $dir!

sub mysystem($) {
  my ($line) = @_;
  my ($name);
  $line =~ m/^\S+/;
  $name = $&;
  print "$line\n";
  system $line;
  if (($? >> 8) > 0) {die "$name failed: $!\n";}
}


-- 
			Martin

martin at gkc.org.uk http://www.cse.dmu.ac.uk/~mward/ Erdos number: 4
G.K.Chesterton web site: http://www.cse.dmu.ac.uk/~mward/gkc/




More information about the Nelug mailing list