So I've been messing around with this a bit too much over the last few days, and I'd like to understand why this is failing. Corion attempted to provide some insight over CB a few days ago, but his insight did not translate into much insight for me. When I execute the following:
#!/usr/bin/perl -w use strict; use IPC::Open3; use Symbol 'gensym'; my @queue = ("Line 1\nThis is the first line\n", "Line 2\nThis is the second line\n", "Line 3\nThis is the third line\n", ); single_thread(@queue); sub single_thread { open my $oldout, ">&", \*STDOUT or die "Can't dup STDOUT: $!"; for (@_) { local *STDOUT; open STDOUT, '>', \my $stdout or die "Can't redirect STDOUT: $ +!"; test($_); print $oldout "STDOUT: $stdout\n" if defined $stdout; close STDOUT; } } sub test { my $line = shift; my $pid = open3(my $wtr, my $rdr, undef, 'cat', '-v'); print $wtr $line; close $wtr; my $content=do{local $/;<$rdr>}; local $\; print STDOUT $content; waitpid( $pid, 0 ); }
I get the output
Line 1 This is the first line Line 2 This is the second line Line 3 This is the third line
This means that when I do the redirect, it mucks up the capture for some reason. If I change sub test to
sub test_mod { my $line = shift; my $content = `echo '$line'`; local $\; print STDOUT $content; }
I get the expected
STDOUT: Line 1 This is the first line STDOUT: Line 2 This is the second line STDOUT: Line 3 This is the third line
and as well if I swap sub single_thread to
sub single_thread { for my $line (@_) { my $pid = open3(my $wtr, my $rdr, undef, 'cat', '-v'); print $wtr $line; close $wtr; my $content=do{local $/;<$rdr>}; local $\; print "STDOUT: $content\n"; } }
I get
STDOUT: Line 1 This is the first line STDOUT: Line 2 This is the second line STDOUT: Line 3 This is the third line
Any suggestions, other than don't do that? As the subroutine name implies, this is ultimately intended for a multithreaded environment. Essentially, I would like to wrap a subroutine that runs an external command so that it transparently supports threads while maintaining contiguity between each thread's output. I've had this working with backticks for a while, but now I have to modify it to separate the streams and I just don't understand why a core module would show such strange behavior.

In reply to STDOUT redirects and IPC::Open3 by kennethk

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.