After dinking around with an expensive three or four days trying to understand IPC::Open3 and trying to make things work I finally got it to work. I thought I would add my 2 cents and hopefully save someone else (or myself somewhere down the road) the same headache.

Yes, I know about IPC::Run. Unfortunately, the host I was required to use did not have it installed and I was not allowed to install any but my own stuff (I could have claimed it as mine for the purpose of getting things done, but I still didn't understand what exactly I was doing and didn't want to be required to fix something I didn't understand when it broke).

First, the samples given here and elsewhere, while very helpful, included some extraneous details that contributed to my confusion.

Given the *simplest* requirement:

  • Call a program using command line arguments and passing data via STDIN, grab both STDOUT and STDERR and process them somehow.
  • All of the examples included code like

    my $IN = IO::File->new_tmpfile;
    or
    local *OUT; open OUT, ">output.log";
    and then proceed to call the open3 with those filehandles.

    They aren't needed, at least for something this simple. Once I realized this I was able to get things working:

    sub callexternalpgm { my ( $cmd, $cmdargs, $rawdata, $processeddata, $err ) = @_; my ( $IN, $OUT, $ERR ); $ERR = gensym(); my $pid; eval{ $pid = open3( $IN, $OUT, $ERR, $cmd, @{ $cmdargs } ) }; return $@ if $@; print $IN $rawdata; close $IN; my $select = new IO::Select; $select->add( $OUT, $ERR ); while(my @ready = $select->can_read) { foreach my $fh (@ready) { my $data; my $length = sysread $fh, $data, 4096; if( ! defined $length || $length == 0 ) { $err .= "Error from child: $!\n" unless defined $length; $select->remove($fh); } else { if($fh == $OUT) { $processeddata .= $data; } elsif($fh == $ERR) { $err .= $data; } else { return undef; } } } } waitpid $pid, 0; # wait for it to die warn $err if $err; return 1; }
    Any comments or improvements would be appreciated. I realize I need to add some checks for references and the like.
    Harley J Pig

    In reply to I got IPC::Open3 to work! by harleypig

    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.