fastfox has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks !

I'm having a little trouble with a small script (the first I wrote in Perl), but not the "standard" way I guess.

I'm creating a tarball from a folder, gzipping it afterwards:

$tarball = "backup_".$time_stamp.".tar"; open(TAR, "$tar cf $tarball $dir/* |"); close(TAR); $gzfile = $tarball.".gz"; open(FILE, $tarball); binmode FILE; $gz = gzopen($gzfile, "wb"); while (my $by = sysread (FILE, $inh, 4096)) { $gz->gzwrite($inh); } $gz->gzclose();

That works well, also the mail which I send with the .gz as attachment works, but then my mail provider refuses to recieve an attachment with an archive within an archive. Is there any trick to get the folder directly into a .gz ?

Thanks for any tips !
CheerS
fastfox

Replies are listed 'Best First'.
Re: gzipping folder without tarring it first
by Corion (Patriarch) on May 06, 2010 at 14:29 UTC

    gzip can only compress single files.

    Maybe you want to use a different archive format, like .zip or .rar? Or maybe you want to send a tar archive of gzipped files, which might be slightly larger yet still pass that virus scanner?

    Also note that you don't have to use open if all you want to do is run an external process. system allows you to run an external process, and backticks allow you to capture the output of a subprocess.

    You can even archive and compress the folder in one go:

    my $tgz = "$tar cf - $dir/* | gzip -9c"; open my $gzipped, "$tgz |" or die "Couldn't run [$tgz]: $!/$?"; binmode $gzipped; $/ = \4096; print while <$gzipped>;

      Sure, .zip would be okay too.

      I just tried a little, but I guess I got something wrong ...

      $zip = Archive::Zip->new() foreach my $membername (map {glob} $dir) { if (-d $membername) { $zip->addTree( $membername, $membername ); } else { $zip->addFile ($membername); } } $zip->writeToFileNamed($archive);

      It says that there's a syntax error near the foreach, but I don't get what it is :-(

        Missing semicolon?

        $zip = Archive::Zip->new() ......................................^
Re: gzipping folder without tarring it first
by moritz (Cardinal) on May 06, 2010 at 14:26 UTC
    gzip just compresses single files; if you want multiple files, you just need the tar step.

    Maybe talk to your email provider? Or use ordinary zip archives instead?

Re: gzipping folder without tarring it first
by BrowserUk (Patriarch) on May 06, 2010 at 14:48 UTC

    See Archive::Zip. It handles putting multiple files in to a single archive.

Re: gzipping folder without tarring it first
by gloryhack (Deacon) on May 06, 2010 at 16:15 UTC
    ... but then my mail provider refuses to recieve an attachment with an archive within an archive.

    I could be wrong, but that sounds just like the dreaded "improperly formatted binary content" error. If this is the case, try Base64 encoding the gzipped content before sending it, and ensure that you're sending the correct MIME headers, too.