Perl6:检查STDIN是否有数据

时间:2018-03-01 15:15:21

标签: perl6

在我的Perl 6脚本中,我想对标准输入进行(最好是非阻塞)检查以查看数据是否可用。如果是这种情况,那么我想处理它,否则我想做其他事情。

示例(shiny):

consumer.p6

作为STDIN-Generator我写了另一个Perl6脚本(#!/usr/bin/perl6 use v6.b; use fatal; sub MAIN() returns UInt:D { while !$*IN.eof { if some_fancy_check_for_STDIN() { #TODO: this needs to be done. for $*IN.lines -> $line { say "Process '$line'"; } } say "Do something Else."; } say "I'm done."; return 0; } ):

producer.p6

如果#!/usr/bin/perl6 use v6.b; use fatal; sub MAIN() returns UInt:D { $*OUT.say("aaaa aaa"); sleep-until now+2; $*OUT.say("nbbasdf"); sleep-until now+2; $*OUT.say("xxxxx"); sleep-until now+2; return 0; } 按预期工作,如果通过consumer.p6调用,则应生成以下输出:

./producer.p6 | ./consumer.p6

但实际上,它会产生以下输出(如果注释掉Process 'aaaa aaa' Do something Else. Process 'nbbasdf' Do something Else. Process 'xxxxx' Do something Else. I'm done. 条件):

if

1 个答案:

答案 0 :(得分:8)

您正在使用旧版本的Perl 6,因为v6.b来自该语言的正式发布之前 因此,我在下面的一些内容可能需要更新的版本。

另外,为什么使用sleep-until now+2代替sleep 2

执行此操作的一种方法是将.lines变为Channel,然后您可以使用.poll

#!/usr/bin/env perl6
use v6.c;

sub MAIN () {
    # convert it into a Channel so we can poll it
    my $lines = $*IN.Supply.lines.Channel;

    my $running = True;
    $lines.closed.then: {$running = False}

    while $running {
        with $lines.poll() -> $line {
            say "Process '$line'";
        }
        say "Do something Else.";
        sleep ½;
    }
    say "I'm done.";
}

请注意,上面的代码目前在my $lines = …行阻止;因此,在第一行进入之前,它不会开始做某事。为了解决这个问题,你可以做以下事情

my $lines = supply {
    # unblock the $*IN.Supply.lines call
    whenever start $*IN.Supply {
        whenever .lines { .emit }
    }
}.Channel;