Как я могу проверить STDIN без блокировки на Perl?

Я пишу свое первое приложение Perl - бот AOL Instant Messenger, который разговаривает с микроконтроллером Arduino, который, в свою очередь, управляет сервоприводом, который будет нажимать кнопку питания на нашем сервере sysadmin, который зависает случайным образом каждые 28 часов или около того,

Я получил все тяжелые вещи, я просто пытаюсь добавить один последний бит кода, чтобы разбить основной цикл и выйти из AIM, когда пользователь вводит "quit".

Проблема заключается в том, что если я пытаюсь читать из STDIN в основном программном цикле, он блокирует процесс до ввода ввода, по существу, делая бота неактивным. Я пробовал тестировать EOF перед чтением, но без кубиков... EOF всегда возвращает false.

Ниже приведен пример кода, с которым я работаю:

while(1) {
    $oscar->do_one_loop();

# Poll to see if any arduino data is coming in over serial port
    my $char = $port->lookfor();

# If we get data from arduino, then print it
    if ($char) {
        print "" . $char ;
    }

    # reading STDIN blocks until input is received... AAARG!
    my $a = <STDIN>;
    print $a;
    if($a eq "exit" || $a eq "quit" || $a eq 'c' || $a eq 'q') {last;}
}

print "Signing off... ";

$oscar->signoff();
print "Done\n";
print "Closing serial port... ";
$port->close() || warn "close failed";
print "Done\n";

Ответ 1

Встроенный Perl select(), который является прохождением системного вызова select(), но для нормальных людей Я рекомендую IO::Select.

Пример кода:

#!/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";
  }
}