Archive::Tar && File::Find

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

Threaded View
I have an issue with File::Find and Archive::Tar
while trying to create a recursive tar file over
a list of files and directories.
Any time when find returns a directory without file
it has a problem to add this or to write into the tar

Use of uninitialized value in pack at
 /usr/lib/perl5/vendor_perl/5.8.5/Archive/ line 1084.

#!/usr/bin/perl -w

use strict;
use File::Find;
use Archive::Tar;


@sources = ( "aFile", "aDir", "bFile", "cFile", "bDir" )

$tar = Archive::Tar->new( );

foreach $source ( @sources ) {
    if( -d $source || -f $source ) {
        find( sub { push @files, $File::Find::name }, $source );

$tar->Archive::Tar->create_archive( 'foo.tar', 1, @files );
$tar->add_files( @files ) or die "$!\n";
$tar->write( 'foo.tar' ) or die "$!\n";

Getting problems with this when find comes to a pure directory

aDir <- problem
aDir/aFile <- no problem
aDir/bDir <- problem
aDir/bDir/cFile <- no problem

Thanks for your inputs?

Re: Archive::Tar && File::Find wrote in news:41178fc0-05c7-402e-99a8-

Quoted text here. Click to load it

No reason to declare a bunch of variables like this.

Quoted text here. Click to load it

Please post code that actually compiles and runs.


my @sources = qw( aFile aDir bFile cFile bDir );

is easier to read.

Quoted text here. Click to load it

This is weird. @source contains files without path information. So, any
files that are not just in the current working directory will not pass
this test.

Quoted text here. Click to load it

Wouldn't it be better to use a single wanted subroutine that adds files
based on a criterion? With this, you call find on aDir and then bDir
when bDir (according to the structure you gave below) is a subdirectory
of aDir and would have been found using the find call on aDir.

Quoted text here. Click to load it

Have you read the documentation? I had not until now and according to
how I read it the create_archive call is not necessary. Also,
Archive::Tar seems to return error strings in $tar->error rather than

Quoted text here. Click to load it

Why the question mark? Aren't you sure you want to thank us for our

Here is a revised version of your script:

C:\Temp\test> cat

use strict;
use warnings;

use File::Basename;
use File::Find;
use Archive::Tar;

my %sources = map { $_ => 1 } qw( aFile aDir bFile cFile bDir );

my $tar = Archive::Tar->new;

find( {wanted => \&wanted, no_chdir => 1 }, '.' );

$tar->write( 'foo.tar' ) or die $tar->error;

sub wanted {
    -f or -d _ or return;

    exists $sources{ fileparse $_ } or return;
    warn "$_\n";

    $tar->add_files( $_ ) or die $tar->error;


C:\Temp\test> t

C:\Temp\test> tar -tf foo.tar
tar: Record size = 7 blocks

(remove .invalid and reverse each component for email address)

comp.lang.perl.misc guidelines on the WWW: /

Site Timeline