从Perl中的管道读取无缓冲数据

时间:2012-03-09 15:29:32

标签: linux perl perl-io

我正在尝试从Perl中的管道读取非缓冲数据。例如,在下面的程序中:

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

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

iostat每隔10秒(5次)吐出数据。你会期望这个程序也这样做。但是,相反它似乎会挂起50秒(即10x5),然后它会扫出所有数据。

如何在不等待EOF的情况下返回任何可用的数据(以无缓冲的方式)?

P.S。我在Windows下看到了很多对此的引用 - 我在Linux下这样做。

4 个答案:

答案 0 :(得分:5)

#!/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 :(得分:1)

如果可以在你的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);
}

答案 2 :(得分:1)

我有以下代码为我工作

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

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

答案 3 :(得分:1)

到目前为止,解决方案对于非缓冲(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);

在我的案例中起作用。