MediaTracker,
I am sure some monk will show you some black magic to accomplish what you are asking for (probably with IPC::Open3). I am not that monk. You have asked to do three things.
  • Create two child processes
  • Make the STDOUT of the first the STDIN of the second
  • Read the STDERR of the first from the parent

    This is actually fairly straight forward if you use files for the location of the STDOUT/STDERR, turn on auto-flush, and perhaps throw in a little File::Tail which is used to read from continously updated files.

  • Step 1, fork off child process number 1.
  • Step 2, change the location of STDOUT to a file in the first child process
    open (SAVEOUT, ">&STDOUT") or die "Unable to copy STDOUT : $!"; open (STDOUT, ">stdout") or die "Unable to open new STDOUT : $!"; select STDOUT; $| = 1;
  • Step 3, change the location of the STDERR to a file in the first child
    open (SAVEERR, ">&STDERR") or die "Unable to copy STDERR : $!"; open (STDERR, ">stderr") or die "Unable to open new STDOUT : $!"; select STDERR; $| = 1; select STDOUT;
  • Step 4, fork off your second child process
  • Step 5, Either open STDIN from the newly create file or use any unique file handle to read from in the second child process
    open (STDINCLONE, "<stdout") or die "Unable to open first process's ST +DOUT : $!";
  • Step 6, open the file for STDERR of the first child process in the parent program as some unique file handle
    open (ERRORS,"<stderr") or die "Unable to open first process's STDERR +: $!";
    Of course if you need to have STDOUT going both to a terminal AND also need to be able to read from it (file) you can still do everything I just described here with IO::Tee.

    Note: The following is assumed:
    1. The child processes are properly fork'd - see perldoc -f fork if needed
    2. The code will be modified appropriately to incorporate the use of File::Tail if required
    3. The two forked child processes are Perl scripts.
    If these are not Perl scripts that you can't modify the source of you can still change the location of the STDOUT by using the > syntax. I am not sure about modifying the location of STDERR on something other than a *nix machine, but 2>stderr would work there. As far as turning on auto-flush for non-Perl script - I don't know.

    Cheers - L~R


    In reply to Re: Pipe two child processes by Limbic~Region
    in thread Pipe two child processes by MediaTracker

    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.