Answering my own question...
scalar(<STDIN>) didn't work, but thanks for the suggestion, it lead me to the
solution.
Assaf Gordon wrote, On 12/15/2010 03:05 PM:
> My goal is to have a tiny perl program, that reads STDIN, grabs
> couple of lines from it, then executes another program which should
> consume the rest of the lines from STDIN.
>
> This works as expected when using shell redirection, but not when
> using pipes.
>
With 'strace', I found that perl slurps a lot of input from STDIN (more than
one line), then use lseek to reposition in STDIN to point right at the second
line.
When STDIN is a file (with redirection), it works:
7852 read(0, "A\nB\nC\nD\nE\n", 4096) = 10
7852 lseek(0, 2, SEEK_SET) = 2
7852 lseek(0, 0, SEEK_CUR) = 2
When STDIN is a pipe, it obviously doesn't work:
7672 read(0, "A\nB\nC\nD\nE\n", 4096) = 10
7672 lseek(0, 2, SEEK_SET) = -1 ESPIPE (Illegal seek)
And so by the time "sort" is executed, data from STDIN is already consumed ;(
The solution I've found is to bypass perlio and use sysread one char at the
time:
==========
#!/usr/bin/perl
use strict;
use warnings;
sub read_line_non_buffered()
{
my $line = '';
while ( 1 ) {
my $c;
my $rc = sysread STDIN, $c, 1;
die "Read error: $!" unless defined $rc;
return $line if $rc==0 && $line;
return undef if $rc==0 && (!$line);
$line .= $c ;
return $line if ( $c eq "\n");
}
}
my $dummy = read_line_non_buffered();
system("sort -r");
==========
If you have better solution (or comments on my solution), I'm happy to hear.
Thanks,
-Assaf.
_______________________________________________
Perl mailing list
[email protected]
http://mail.perl.org.il/mailman/listinfo/perl