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

I have a much larger program that this goes with, but even the smaller example does not seem to work. I tried initially to use the pipe command, and then switched to open(READ, "-|") command -- but both exhibit the same behavior: I do not get any data from the child until the child closes his end. Here is my example code:

#!/usr/bin/perl -w use strict; if (my $pid = open(READ, "-|")) { print "child said: '", <READ>, "'; ",time,"\n"; print "child said: '", <READ>, "'; ",time,"\n"; } else { print "hello; ",time,"\n"; sleep 2; print "how are you; ",time,"\n"; }
I receive this as output:
gryn@echor:~$ ./testcase.pl child said: 'hello; 1005587480 how are you; 1005587482 '; 1005587482 child said: ''; 1005587482

I'm quite perplexed, and I've read over and over the various examples in the documentations (such as perlipc's numerous ones). I just can figure it out.

I am running with perl 5.6, on a intel debian unstable box; in case that matters.


Ciao,
Gryn

Replies are listed 'Best First'.
Re: Open, ye! And read from your child!
by runrig (Abbot) on Nov 12, 2001 at 23:08 UTC
    Along with having buffering on, your <READ> is in list context, sucking up all input, which doesn't appear to be what you want. Try this:
    $|++; if (my $pid = open(READ, "-|")) { my $line = <READ>; print "child said: [", $line, "]; ",time,"\n"; $line = <READ>; print "child said: [", $line, "]; ",time,"\n"; } else { print "hello; ",time,"\n"; sleep 2; print "how are you; ",time,"\n"; }

      Doh! You would think a (relatively) seasoned Perl Junkie would have noticed that list context blurp. Ok the new code that works is:

      #!/usr/bin/perl -w use strict; if (my $pid = open(READ, "-|")) { print "child said: '", scalar <READ>, "'; ",time,"\n"; print "child said: '", scalar <READ>, "'; ",time,"\n"; } else { $|=1; print "hello; ",time,"\n"; sleep 2; print "how are you; ",time,"\n"; }
      And output:
      gryn@echor:~$ ./testcase.pl child said: 'hello; 1005597768 '; 1005597768 child said: 'how are you; 1005597770 '; 1005597770

      The buffering is necessary, as you all pointed out. However, with the list context problem in the way, I couldn't figure out where to properly put the (de)buffering until it was fixed.

      Thanks and kudos to you three,
      Gryn
Re: Open, ye! And read from your child!
by belg4mit (Prior) on Nov 12, 2001 at 23:01 UTC
    Looks like buffering is getting you, try disabling it (well setting it to auto-flush rather):
    select(READ); $|=1;
Re: Open, ye! And read from your child!
by Zaxo (Archbishop) on Nov 12, 2001 at 23:17 UTC

    The parent reads READ in list contest, so the first print prints everything child has to say. The parent's second print statement immediately gets eof.

    Update: Oops, kept this up too long before answering, didn't mean to dup runrig's answer

    After Compline,
    Zaxo