Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl, disable buffering input

Tags:

perl

buffering

There is a file:

:~$ cat fff
qwerty
asdf
qwerty
zxcvb

There is a script:

:~$ cat 1.pl
#!/usr/bin/perl
print <STDIN>

The command works as expected:

:~$ cat fff | perl -e 'system("./1.pl")'
qwerty
asdf
qwerty
zxcvb

But this command will not work as expected: the first <STDIN> reads all the data, not a single line. How to disable buffering for <STDIN>?

:~$ cat fff | perl -e '$_ = <STDIN>; system("./1.pl")'
:~$
like image 313
drlexa Avatar asked Sep 10 '12 12:09

drlexa


1 Answers

There are two Perl processes here - the first that assigns $_ = <STDIN> and calls system, and the second that does print <STDIN>

Although only the first line of the stream is read into $_ by the first process, behind the scenes Perl has filled its buffer with data and left the stream empty

What is the purpose of this? The only way that comes to mind to do what you ask is to read all of the file into an array in the first process, and then remove the first line and send the rest in a pipe to the second script

All of this seems unnecessary, and I am sure there is a better method if you will describe the underlying problem

Update

Since you say you are aware of the buffering problem, the way to do this is to use sysread, which will read from the pipe at a lower level and avoid the buffering

Something like this will work

cat fff | perl -e 'while (sysread(STDIN, $c, 1)) {$_ .= $c; last if $c eq "\n"} system("./1.pl")'

But I don't like recommending it as what you are doing seems very wrong and I wish you would explain your real goal

like image 157
Borodin Avatar answered Oct 21 '22 22:10

Borodin