Perl에서 차단하지 않고 어떻게 STDIN을 테스트할 수 있나요?

StackOverflow https://stackoverflow.com/questions/14118

  •  08-06-2019
  •  | 
  •  

문제

저는 첫 번째 Perl 앱을 작성 중입니다. Arduino 마이크로컨트롤러와 통신하는 AOL 인스턴트 메신저 봇입니다. 이 봇은 시스템 관리자 서버의 전원 버튼을 누르는 서보를 제어합니다. 이 봇은 약 28시간마다 무작위로 정지됩니다.

어려운 작업은 모두 마쳤습니다. 사용자가 'quit'를 입력하면 메인 루프를 중단하고 AIM에서 로그아웃하기 위한 마지막 코드를 추가하려고 합니다.

문제는 기본 프로그램 루프의 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";
도움이 되었습니까?

해결책

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";
  }
}

다른 팁

나는 그것을 발견했다 IO::선택 파이프라인의 업스트림 프로세스가 종료되거나 입력이 파일에서 오는 경우와 같이 STDOUT이 닫히는 한 잘 작동합니다.그러나 출력이 진행 중인 경우(예: "tail -f"에서) 부분 데이터가 버퍼링됩니다. <STDIN> 표시되지 않습니다.대신 버퍼링되지 않은 시스레드:

#!/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);
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top