In Automated module install, I started to look at creating a simple script to untar some tarballs, and automatically install them. I have something that, at least before I started mangling it, was working on Linux. So I tried on Windows. Didn't get too far, I might mention. Perhaps someone here with a bit more Windows experience than I could shed some light.

Environment: ActiveState 5.8.0, WindowsXP, and lots of Cygwin tools. (I'm hoping we get this upgraded to 5.8.6 soon - so if that's the solution, I'll just apply that pressure.)

The command works fine if I run it at the command prompt, so it's not a lack of the proper tooling (gunzip and tar are both present).

=item do_pipe_command Mostly-simply wrapper around open for piping from a command. Since we generally want to capture stderr, too, we redirect stderr to stdout in the command, so we get it all in a single filehandle. =cut sub do_pipe_command { print 'Running: ', join(' ', @_[1..$#_]), $/; my $pid = open ($_[0], '-|'); return $pid if $pid; # child - pipe the stderr to the stdout before exec'ing. open STDERR, '>&', \*STDOUT; my @cmd = @_[1..$#_]; if ($^O =~ /MSWin/i) { @cmd = (qw(cmd.exe /c), join(' ',@cmd)); } exec @cmd; } =item extract_tarball Tries to untar the tarball. Returns the directory name thusly created. =cut sub extract_tarball { my $tarball = shift; my $cmd = ''; if ($tarball =~ /\.tar\.gz$/) { $cmd = "gunzip -c $tarball | "; } elsif ($tarball =~ /\.tar\.Z$/) { $cmd = "zcat $tarball | "; } elsif ($tarball =~ /\.tar$/) { $cmd = "cat $tarball | "; } else { die "Can't figure out how to untar $tarball"; } $cmd .= 'tar -xvf -'; print "Running $cmd\n"; my $subdir; do_pipe_command my $tar, $cmd or die "Failed to run $cmd: $!"; while (my $l = <$tar>) { print $l; next if $subdir; $subdir = $1 if $l =~ m:^(.*?)[/\\]:; } $subdir; }
The problem seems to be where I try to run the open. fork works fine that I can test, but this seems to go all wonky on me. The error message is:
Running gunzip -c Cache-Repository-0.01.tar.gz | tar -xvf - Running: gunzip -c Cache-Repository-0.01.tar.gz | tar -xvf - '-' is not recognized as an internal or external command, operable program or batch file. Use of uninitialized value in string eq at e:/perl5.8.0/lib/File/Spec/ +Unix.pm line 77.
Yet, as I said, if I run the given command at the command prompt manually, it works fine.

I just installed ActiveState 5.8.6 ... different uninitialized value error message, but same "not recognized" message.

As I'm writing this, I'm starting to wonder if opening '-|' is even going to work on Windows, or am I going to have to resort to some more trickery to get what I want? Namely, a way to get the directory that the untar command is doing. (I wish Archive::Tar and Compress::Zlib were part of the standard perl distribution!)

Update: After reading tye's recommendation, I noticed IPC::Open3 has documented that this is a problem, so I'm going to have to replace the open call with something else. Thanks!

Update: As a confirmation, the new do_pipe_command is:

sub do_pipe_command { print 'Running: ', join(' ', @_[1..$#_]), $/; my @cmd = @_[1..$#_]; my $wtr; require IPC::Open3; my $pid = IPC::Open3::open3($wtr, $_[0], undef, @cmd); }
It works perfectly. No need to launch cmd.exe (which may be because my @cmd is always a single string anyway, at least when I'm chaining subprocesses together in their own pipe). I do realise that this will leave a zombie process behind (at least on unix), but that should be automatically cleaned up when we exit, and this is a very short-lived process anyway. It runs on Linux in under 5 seconds currently, so a few zombies is pretty minor.


In reply to opening '-|' on Windows by Tanktalus

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.