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

If I am calling 1 perl script from another like this:
open(P2,"$perl_script2 |"); while(<P2>) { print; }
how can I get the output as it happens? Both scripts have $|=1 but that doesn't seem to be enough. Thanks.

Replies are listed 'Best First'.
Re: Nested line buffered output
by ikegami (Patriarch) on Jun 01, 2010 at 18:33 UTC

    readline (aka <>) reads until a newline or eof is encountered before returning. You want sysread since it returns as soon as data is available.

    for (;;) { my $read = sysread($fh, my $buf, 64*1024); die("Can't read from pipe: $!\n") if !defined($read); last if !$read; print $buf; }
      Thank you all for the replies. The sysread example worked exactly as I needed it to.
Re: Nested line buffered output
by Anonymous Monk on Jun 01, 2010 at 17:34 UTC

    The code you posted lacks any mention of $|=1

    You need to use strict and use warnings.

    You also really need to check to see whether the open succeeded or not and print the reason when it fails.

      Okay, I can write two sample programs to illustrate my question.

      p1.pl
      #!/usr/bin/perl use strict; use warnings; $|=1; my $p2 = "/tmp/p2.pl"; open(P2,"$p2 |") || die "P2: $p2 - $!\n"; while(<P2>) { print; }
      p2.pl
      #!/usr/bin/perl use strict; use warnings; $|=1; my $i; for $i (1..10) { print "."; sleep 1; } print "\n";
      The output of p2.pl is 1 dot every second for 10 seconds but the output of p1.p1 is 10 dots after 10 seconds. Thanks.
        The problem is in the title: "line buffered". You're reading P2 line-by-line, but printing only one line total in p2.pl in the first place. Try this in p1.pl:
        #!/usr/bin/perl use strict; use warnings; $|=1; my $p2 = "./p2.pl"; open(P2,"$p2 |") || die "P2: $p2 - $!\n"; while( read( P2, $_, 1 ) ) { # fixed as per [ikegami]'s post below print; }

        BTW, you should probably be using a lexical filehandle, but given the short example I won't complain too loudly. ;-)

        Update: fixed bug in read as pointed out by ikegami in Re^4: Nested line buffered output.