I stumbled upon this problem when decided to write an automated script for backing up my projects. The first solution was to use
Archive::Rar module, but there are 2 catches: you need to have winRar installed and you need the Archive::Rar module itself.
Finding this not acceptable, I looked into the Archive module to find the
Archive::Tar quite good!
The only problem was that it didn't want to simply archive a specified directory and all of it's contents, instead you need to provide the list of all the files you want archived in a list.
If you simply provide it with a list of full absolute paths to files, you'll end up with the archive containing all your directory structure like having folders 'D:', 'Program Files', 'etc' and so on. What you can do is first
chdir() (not everyone knows it's possible to change the current working directory from inside the script) to the directory one level above the one you're going to archive and then perform all operations relative to that path which is much more convinient.
To add all the files in nested folders you have to recursively traverse the directory structure either manually or, for example, using
File::Find. We'll do it th latter way as File::Find is also a standard perl module.
(you can grab the full fledged version of the script
here [http://github.com/chhh/backup/blob/master/backup.pl])
use Archive::Tar;
use File::Find;
# assume you have the following folder for archiving
# d:/some_data/folder_for_archiving
# you can work with this path and split it using RegEx or how
# ever you like
# you can also use Cwd module to get the absolute path like
# this:
# use Cwd qw/abs_path/;
# my $abs_dir_path = abs_path($some_relative_path);
# for this example we'll keep it even simpler
my $abs_dir_path = 'd:/some_data/';
my $dir_name = 'folder_for_archiving';
my $archive_filename = 'archived_filder';
# changing the working directory
chdir $abs_dir_path
or die "Can't change dir to $abs_dir_path: $!\n";
# The find() function recursively traverses the directory
# structure returning
# the name of each file in a special variable $File::Find::name,
# it uses a
# callback function for each file, here we used anonymous
# function defined
# right inside the find() call, that pushes each filename
# to our @files array.
my @files;
find(sub {push @files,$File::Find::name},$folder_for_archiving);
# the 1st argument to Archive::Tar is the archive name,
# 2nd level of
compression (1-9), 3rd is argument list
if ( !Archive::Tar->create_archive(
"$abs_dir_path/$archive_filename.tar",
5,
@files)) {
print "Archivation failed.\n";
}
print "Archivation complete.\n";
(you can grab the full fledged version of the script
here [http://github.com/chhh/backup/blob/master/backup.pl])