The following was a quick Perl based backup script I could use toback up my working documents and projects to make sure I didn't loseanything if I experienced a random crash. I chose to use Perl because Iwanted something a little more robust than just a straight copy ofitems (such as you could do with a batch file). I don't like thewindows native backup feature because I've had bad experiences with thebackups getting corrupted or being difficult to restore.
I'm copying from my local D:\ drive to a remote SMB mounted U:\drive.
The script only backs up one way, and it won't remove items thathave been deleted (I figure in the short term this could be a bonus butit may become a headache over time). The script will recursively dropthrough directories and copy any files to backup that either havechanged or do not appear on the backup drive.
There is also a primitive exclusion list. I have some large files onmy local drive in the "My Music" folder that I don't want to botherbacking up to the remote directory and some random empty "New Folder"folders that I used for testing. The exclusion file will make surethese directories are ignored.
The other trick with this script was getting it to run withoutinterrupting my work. I decided to use the windows system taskscheduler, but created a custom batch file to start the process so itwould be minimized. The batch file is pretty simple, I just used the"/min" option in the start command to avoid the hassle of a windowpopping up and stealing focus. The batch file is simply:
I'm copying from my local D:\ drive to a remote SMB mounted U:\drive.
The script only backs up one way, and it won't remove items thathave been deleted (I figure in the short term this could be a bonus butit may become a headache over time). The script will recursively dropthrough directories and copy any files to backup that either havechanged or do not appear on the backup drive.
There is also a primitive exclusion list. I have some large files onmy local drive in the "My Music" folder that I don't want to botherbacking up to the remote directory and some random empty "New Folder"folders that I used for testing. The exclusion file will make surethese directories are ignored.
The other trick with this script was getting it to run withoutinterrupting my work. I decided to use the windows system taskscheduler, but created a custom batch file to start the process so itwould be minimized. The batch file is pretty simple, I just used the"/min" option in the start command to avoid the hassle of a windowpopping up and stealing focus. The batch file is simply:
@ECHO OFF
start /min perl backuper.pl
The perl file is much larger, and logs its progress to a file calledbackuper.log that sits in the same directory as the perl script. I'msure I could add quite a few more features (like filename wildcards forexclusion so I didn't back up MP3 files for instance) but this barebones works well enough for now.#! C:\Perl\bin
#
# Purpose: This Perl based backup client designed to examine
# folder contents and update them on the appropriate remote
# backup system.
#
# ANU 007 TIGER (pctipsbyanu@yahoo.com)
#
use strict;
use File::Copy;
use File::Compare;
#log file options
my $logFile = 'backuper.log';
my $outputLog = checkLogFile($logFile) or die("Error opening log file -- $@");
my @exclusion_list = ('.', '..', 'My Music', 'New Folder');
my %directories = ( 'D:\Documents and Settings\anu007tiger\My Documents', 'U:\mydocs',
'D:\Documents and Settings\anu007tiger\Desktop\bin', 'U:\bin');
while ( (my $ldir, my $rdir) = each(%directories) ) {
chdir $ldir or fatal_error("Couldn't change to $ldir");
if (! -d $rdir) {
fatal_error("Couldn't open the remote directory $rdir");
}
my $remoteFileName;
my $tmpDirName;
my $tmpRemDirName;
read_copy($ldir, $rdir);
}
######################
# SUBROUTINES #
######################
sub read_copy {
my $local_dir = $_[0] or fatal_error("No local directory specified. $!");
my $remote_dir = $_[1] or fatal_error("No remote directory specified. $!");
if (! -d $remote_dir ) {
mkdir($remote_dir) or fatal_error("Failed to create $remote_dir. $!");
}
opendir(DIRHANDLE, $local_dir) || fatal_error("Cannot opendir $local_dir. $!");
foreach my $name (sort readdir(DIRHANDLE)) {
if (! -d $name ) {
my $remoteFileName = $remote_dir . '\\' . $name ;
my $localFileName = $local_dir . '\\' . $name;
if (! -d $remote_dir) {
fatal_error("$remoteFileName doesn't seem to exist? $!");
}
if (! -d $localFileName) {
if ( checkBackup($localFileName, $remoteFileName) ) {
copy("$localFileName", "$remoteFileName") or die qq(Cannot copy "$localFileName" to "$remoteFileName": $!) ;
logIt("Backed up $localFileName to $remoteFileName");
}
}
elsif ( -d $localFileName && (! check_exclusion($name)) ) {
my $tmpDirName = $local_dir . '\\' . $name;
my $tmpRemDirName = $remote_dir . '\\' . $name;
read_copy($tmpDirName, $tmpRemDirName);
}
}
else {
if (! check_exclusion($name) ) {
my $dir1 = $local_dir . '\\' . $name;
my $dir2 = $remote_dir . '\\' . $name;
read_copy($dir1, $dir2);
}
}
}
closedir(DIRHANDLE);
}
sub checkBackup {
my $file1 = $_[0] or fatal_error("Missing first file in checkBackup(). $!");
my $file2 = $_[1] or fatal_error("Missing second file in checkBackup(). $!");
#check to see if we should back these files up
if (compare("$file1","$file2") == 0) {
return 0;
}
else {
return 1;
}
}
sub check_exclusion {
#checks the exclusion list for stuff not to copy
my $file = $_[0];
foreach my $item (@exclusion_list) {
if ($file eq $item) {
return 1;
}
}
return 0;
}
sub fatal_error {
#die and log the error
my $error_message = $_[0];
$error_message = "Fatal Error: " . $error_message;
logIt($error_message);
die ($error_message . "\n");
}
#####################
# Logging #
#####################
sub logIt {
#logs errors.
my $message = $_[0];
my @fullTime = localtime(time());
my $time = ($fullTime[5] + 1900) . "/" . (addZero($fullTime[4] + 1)) . "/";
$time .= addZero($fullTime[3]). " " . addZero($fullTime[2]) . ":";
$time .= addZero($fullTime[1]) . ":" . addZero($fullTime[0]);
my $logMessage = $time . "> $message \n";
print $outputLog $logMessage;
}
sub checkLogFile {
#checks the output files to make sure they're valid
my $file = $_[0];
my $openFile;
my $status = (stat($file))[7];
if (! $status) { $status = 0;}
if ( $status != 0) {
open($openFile, ">>" . $file) or die("Couldn't open log file for appending " . $file);
return $openFile;
}
else {
open($openFile, ">" . $file) or die("Couldn't create new log file " . $file);
return $openFile;
}
}
sub addZero {
#formats output to double digit
if (length($_[0]) < 2) {
return "0" . $_[0];
}
else {
return $_[0];
}
}
Enjoy SCRIPTING...
0 comments:
Post a Comment