Чтение небуферизованных данных из канала в Perl - PullRequest
7 голосов
/ 09 марта 2012

Я пытаюсь прочитать данные без буфера из канала в Perl.Например, в приведенной ниже программе:

open FILE,"-|","iostat -dx 10 5";
$old=select FILE;
$|=1;
select $old;
$|=1;

foreach $i (<FILE>) {
  print "GOT: $i\n";
}

iostat выплевывает данные каждые 10 секунд (пять раз).Вы ожидаете, что эта программа сделает то же самое.Однако вместо этого он, кажется, зависает в течение 50 секунд (то есть 10x5), после чего выплевывает все данные.

Как я могу вернуть все доступные данные (вбез буферизации), не дожидаясь полного завершения EOF?

PS Я видел многочисленные ссылки на это в Windows - я делаю это в Linux.

Ответы [ 4 ]

5 голосов
/ 09 марта 2012
#!/usr/bin/env perl

use strict;
use warnings;



open(PIPE, "iostat -dx 10 1 |")       || die "couldn't start pipe: $!";

while (my $line = <PIPE>) {
    print "Got line number $. from pipe: $line";
}

close(PIPE)                           || die "couldn't close pipe: $! $?";
1 голос
/ 09 февраля 2013

До сих пор решения не работали для меня в отношении небуферизации (Windows ActiveState Perl 5.10).

Согласно http://perldoc.perl.org/PerlIO.html, "Чтобы получить небуферизованный поток, укажите небуферизованный слой (например:unix) в открытом вызове: ".

Так

open(PIPE, '-|:unix', 'iostat -dx 10 1') or die "couldn't start pipe: $!";

while (my $line = <PIPE>) {
    print "Got $line";
}

close(PIPE);

, который работал в моем случае.

1 голос
/ 09 марта 2012

у меня ниже код работает на меня

#!/usr/bin/perl
use strict;
use warnings;
open FILE,"-|","iostat -dx 10 5";

while (my $old=<FILE>)
{
  print "GOT: $old\n";
}
1 голос
/ 09 марта 2012

Если в вашем Perl-скрипте нормально подождать вместо команды linux, это должно сработать.Я не думаю, что Linux вернет управление сценарию Perl до завершения выполнения команды.

#!/usr/bin/perl -w
my $j=0;
while($j!=5)
{
    open FILE,"-|","iostat -dx 10 1";
    $old=select FILE;
    $|=1;
    select $old;
    $|=1;

    foreach $i (<FILE>)
    {
        print "GOT: $i";
    }
    $j++;
    sleep(5);
}
...