如何在不阻止Perl的情况下测试STDIN?
时间:2020-03-05 18:40:14 来源:igfitidea点击:
我正在编写我的第一个Perl应用程序-一个与Arduino微控制器对话的AOL Instant Messenger机器人,该机器人又控制一个伺服器,该伺服器将按下sysadmin服务器上的电源按钮,该服务器每28个小时左右随机冻结。
我已经完成了所有艰苦的工作,我只是想添加最后一点代码来打破主循环,并在用户键入"退出"时退出AIM。
问题是,如果我尝试从主程序循环中的STDIN读取数据,它将阻塞该过程,直到输入了输入,这实际上使该bot处于非活动状态。在阅读之前,我尝试过测试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";
解决方案
回答
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"; } }