How can I test STDIN without blocking in Perl?

前端 未结 2 1988
孤街浪徒
孤街浪徒 2021-02-19 19:05

I\'m writing my first Perl app -- an AOL Instant Messenger bot that talks to an Arduino microcontroller, which in turn controls a servo that will push the power button on our sy

相关标签:
2条回答
  • 2021-02-19 19:48

    The Perl built-in is select(), which is a pass-through to the select() system call, but for sane people I recommend IO::Select.

    Code sample:

    #!/usr/bin/perl
    
    use IO::Select;
    
    $s = IO::Select->new();
    $s->add(\*STDIN);
    
    while (++$i) {
      print "Hiya $i!\n";
      sleep(5);
      if ($s->can_read(.5)) {
        chomp($foo = <STDIN>);
        print "Got '$foo' from STDIN\n";
      }
    }
    
    0 讨论(0)
  • 2021-02-19 19:58

    I found that IO::Select works fine as long as STDOUT gets closed, such as when the upstream process in the pipeline exits, or input is from a file. However, if output is ongoing (such as from "tail -f") then any partial data buffered by <STDIN> will not be displayed. Instead, use the unbuffered sysread:

    #!/usr/bin/perl
    use IO::Select;
    $s = IO::Select->new(\*STDIN);
    
    while (++$i) {
            if ($s->can_read(2)) {
                    last unless defined($foo=get_unbuf_line());
                    print "Got '$foo'\n";
            }
    }
    
    sub get_unbuf_line {
            my $line="";
            while (sysread(STDIN, my $nextbyte, 1)) {
                    return $line if $nextbyte eq "\n";
                    $line .= $nextbyte;
            }
            return(undef);
    }
    
    0 讨论(0)
提交回复
热议问题