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

How might I write a Perl script that lies in the cgi-bin that, when ran, downloads a tar.gz and extracts its contents into a directory outside the cgi-bin?

The directory structure might look like this:
-HTML
--IMG
---extract the files here
-CGI-BIN
--the script is here

Does anyone know how to do this?

Replies are listed 'Best First'.
Re: Tar GZip Question
by Aristotle (Chancellor) on Oct 30, 2002 at 01:20 UTC
    That's two tasks: downloading and extracting. Perl modules that address those are LWP for downloading and Archive::Tar for extraction. You might also use system to call wget or curl for downloading and tar for extraction - see man wget and man tar. Or use a mix of both, if necessary/desired.

    Makeshifts last the longest.

      I tried to do that. The problem is getting it to extract intp a different directory. I tried this:
      mirror("http://www.digitmania.holowww.com/targz/katt0$number.tar.gz", + "katt0$number.tar.gz"); system("mv", "katt0$number\.tar\.gz", "\.\.\/html\/img\/katt0$number\ +.tar\.gz"); system("tar", "zxvf", "\.\.\/html\/img\/katt0$number\.tar\.gz");
      It downloads and moves the files, but won't extract them in that directory. Do you know what might be wrong (or have an alternative solution)?
        man tar has what you need:
        -C, --directory DIR change to directory DIR
        You needn't move the file either, it's enough to pass that parameter. Otherwise, tar will of course work in the current directory.

        Makeshifts last the longest.

        My psychic powers tell me you are doing this through CGI and the anonymous user "httpd" or "nobody" or "iusr_xxx" does not have permission to write to the directory in question.

        Second, what's with all the backslashes? Yech!

        Third, You should use the rename function within perl (or the File::Copy module) to do your moving, not an external command.

        Fourth, you should use Archive::Tar to handle your extraction, not an external command.

        Fifth, whether you use modules or external commands to do your file handling and extraction, you should always, *always*, ALWAYS return the error message from the operation ($! for perl system functions, $? for system commands.

        --
        Regards,
        Helgi Briem
        helgi AT decode DOT is

Re: Tar GZip Question
by l2kashe (Deacon) on Oct 30, 2002 at 05:05 UTC
    To deal with the .gz extension Compress::Zlib. Right in the documentation, it shows a simple gzip -d snippet via the module. Someone else mentioned Archive::Tar I believe it was. I've never used it, but it sounds like it could be close to what you are looking for. ;)

    I am also assuming the system calls I've included below are in fact the perl system functions, as opposed to your own. You dont need to escape the . in system commands. So they can be rewritten like so..
    from:
    system("mv", "katt0$number\.tar\.gz", "\.\.\/html\/img\/katt0$number\.tar\.gz");
    to:
    system("/usr/bin/mv ./katt0$number.tar.gz ../html/img/katt0$number.tar.gz");
    But that isnt quite perlish enough.. Lets try
    my $tarball = "katt0$number.tar.gz"; rename("$tarball", "../html/img/$tarball");
    Now on top of that the call to tar will extract the contents of the tarball in the present working directory. I do not know what functionality Archive::Tar will give, but I can almost guarantee that it will allow you to extract the contents to another directory. If not, you'll need play with your ENV hash, and alter the PWD key. There may be a more perlish way to do that, I'm not sure.

    At the very least that should get you rolling in the right direction.

    /* And the Creator, against his better judgement, wrote man.c */
      to:
      system("/usr/bin/mv ./katt0$number.tar.gz ../html/img/katt0$number.tar.gz");
      Err no. You're right he doesn't need to escape the dots of course, but his system LIST form avoids the shell, yours doesn't.
      rename("$tarball", "../html/img/$tarball");

      That is usually better, but don't forget to mention the caveat that mv(1) will work across filesystem boundaries and rename won't. File::Copy is what you usually want when you're using rename. (Oh, and why the quotes around $tarball?)

      Playing with $ENV{PWD} does not do anything other than confuse yourself - it doesn't actually change the working directory. You either want to actually chdir or (as I posted above) use the -C option to tar.

      Makeshifts last the longest.

        I didn;t know about that functionality in regards to the LIST context of the system command..

        I quoted $tarball cause I'm paranoid.. I always quote, or use braces liberally... I'd rather be overly paranoid and make sure the guy coming after me knows exactly what I meant when I wrote it as opposed to leaving some ambiguity...

        And thanks for the chdir ... couldn't remember the function name, but I knew it was buried in there somewhere..

        /* And the Creator, against his better judgement, wrote man.c */