Archive::Tar && File::Find

Discussion in 'Perl Misc' started by bernd.fischer-krellenberg@web.de, Apr 30, 2009.

  1. Guest

    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
    aDir/bDir
    it has a problem to add this or to write into the tar
    archive

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


    #!/usr/bin/perl -w

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

    my(
    @sources,
    $source,
    $tar,
    @files
    );

    @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

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


    Thanks for your inputs?
     
    , Apr 30, 2009
    #1
    1. Advertising

  2. wrote in news:41178fc0-05c7-402e-99a8-
    :

    > 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
    > aDir/bDir
    > it has a problem to add this or to write into the tar
    > archive
    >
    > Use of uninitialized value in pack at
    > /usr/lib/perl5/vendor_perl/5.8.5/Archive/Tar.pm line 1084.
    > #!/usr/bin/perl -w
    >
    > use strict;
    > use File::Find;
    > use Archive::Tar;
    >
    > my(
    > @sources,
    > $source,
    > $tar,
    > @files
    > );


    No reason to declare a bunch of variables like this.

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


    Please post code that actually compiles and runs.

    Also:

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

    is easier to read.

    > $tar = Archive::Tar->new( );
    >
    > foreach $source ( @sources ) {
    > if( -d $source || -f $source ) {


    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.

    > find( sub { push @files, $File::Find::name }, $source );


    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.

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


    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
    $!.

    > aFile
    > aDir <- problem
    > aDir/aFile <- no problem
    > aDir/bDir <- problem
    > aDir/bDir/cFile <- no problem
    >
    > Thanks for your inputs?


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

    Here is a revised version of your script:

    C:\Temp\test> cat t.pl
    #!/usr/bin/perl

    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;
    return;
    }

    __END__

    C:\Temp\test> t
    ../aDir
    ../aDir/aFile
    ../aDir/bFile
    ../aDir/bDir
    ../aDir/bDir/cFile

    C:\Temp\test> tar -tf foo.tar
    tar: Record size = 7 blocks
    ../aDir
    aDir/aFile
    aDir/bFile
    aDir/bDir
    aDir/bDir/cFile

    --
    A. Sinan Unur <>
    (remove .invalid and reverse each component for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://www.rehabitation.com/clpmisc/
     
    A. Sinan Unur, Apr 30, 2009
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Claudio Grondi
    Replies:
    4
    Views:
    557
    Claudio Grondi
    Aug 20, 2005
  2. Replies:
    2
    Views:
    427
    Michael Hoffman
    Apr 24, 2007
  3. Simon Mullis
    Replies:
    2
    Views:
    110
    Simon Mullis
    Sep 28, 2007
  4. benoit Guyon
    Replies:
    2
    Views:
    219
    benoit Guyon
    Jul 26, 2005
  5. Justin C
    Replies:
    3
    Views:
    108
    Justin C
    Jul 7, 2010
Loading...

Share This Page