Чтение небуферизованных данных из канала в Perl

Я пытаюсь прочитать данные без буфера из канала в 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 ответа

Решение
#!/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: $! $?";

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

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

while (my $old=<FILE>)
{
  print "GOT: $old\n";
}

Решения до сих пор не работали для меня в отношении небуферизации (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);

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

Если в вашем скрипте 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);
}
Другие вопросы по тегам