2013-05-16 8 views
0

나는 펄에 newb '을 해요, 그리고표시 bash는 스크립트 출력 - 스크립트

에 유래에 내가 발견 저주 (저주 : UI)와 Perl로 간단한 스크립트의 실행을하려고 저주 솔루션은 Perl에서 Bash 스크립트의 출력을 실시간으로 인쇄합니다.

하지만이 출력을 TextEditor 필드에 쓰려면 Curses 스크립트로 할 수 없습니다. 예를 들어

, 펄 스크립트 :

#!/usr/bin/perl -w 

use strict; 
use Curses::UI; 
use Curses::Widgets; 
use IO::Select; 

my $cui = new Curses::UI(-color_support => 1); 

[...] 

my $process_tracking = $container_middle_right->add(
    "text", "TextEditor", 
    -readonly  => 1, 
    -text   => "", 
); 

sub launch_and_read() 
{ 
    my $s = IO::Select->new(); 
    open my $fh, '-|', './test.sh'; 
    $s->add($fh); 

    while (my @readers = $s->can_read()) { 
     for my $fh (@readers) { 
      if (eof $fh) { 
       $s->remove($fh); 
       next; 
      } 
      my $l = <$fh>; 
      $process_tracking->text($l); 
      my $actual_text = $process_tracking->text() . "\n"; 
      my $new_text = $actual_text . $l; 
      $process_tracking->text($new_text); 
      $process_tracking->cursor_to_end(); 
     } 
    } 
} 

[...] 

$cui->mainloop(); 

이 스크립트는 launch_and_read을 시작하는 버튼이 있습니다().

그리고 test.sh :

#!/bin/bash 
for i in $(seq 1 5) 
do 
    sleep 1 
    echo "from $$ : $(date)" 
done 

결과는 bash는 스크립트가 실행되는 동안 내 응용 프로그램 동결이며, 최종 출력이 말에 내 문서 편집기 필드에 작성됩니다.

펄 스크립트를 차단하지 않고 쉘 스크립트에서 발생한 일을 실시간으로 보여주는 솔루션이 있습니까? 이 질문은 바보 같은 것 같다 경우

많은 감사하고 죄송합니다 : X 당신은 차단할 수 없습니다

답변

0

. Curses의 루프는 이벤트를 처리하기 위해 실행해야합니다. 따라서 투표해야합니다. timeout이 0 인 select을 사용하여 폴링 할 수 있습니다.

my $sel; 

sub launch_child { 
    $sel = IO::Select->new(); 
    open my $fh, '-|', './test.sh'; 
    $sel->add($fh); 
} 

sub read_from_child { 
    if (my @readers = $sel->can_read(0)) { 
     for my $fh (@readers) { 
     my $rv = sysread($fh, my $buf, 64*1024); 
     if (!$rv) { 
      $sel->remove($fh); 
      close($fh); 
      next; 
     } 

     ... add contents of $buf to the ui here ... 
     } 
    } 
} 

launch_child(); 
$cui->set_timer(read_from_child => \&read_from_child, 1); 
$cui->mainloop(); 

테스트되지 않음.

개행이 개행을 받기 전까지는 readline (<>)에서 sysread으로 변경 했으므로주의하시기 바랍니다. read 또는 readline과 같은 차단 호출을 사용하면 select을 사용할 수 없습니다. 또한 read 또는 readline과 같은 버퍼링 호출을 사용하면 select은 실제로있을 때 아무 것도 기다리지 않는다고 말할 수 있습니다. readreadlineselect과 함께 사용하지 마십시오.

+0

if ($ sel-> can_read (0)) {'if (my @readers = $ sel-> can_read (0)) {'로 바뀌 었습니다. TextEditor를 새로 고치려면 뭔가를해야합니다 (키를 눌러 목록 선택 변경). 내가 아무것도하지 않으면 저주가 새로 고침되지 않습니까? – user2388767

+0

저의 이전 코멘트에 더하여 : Curses는 입력을받을 때마다 메인 루프를 시작하는 것으로 보입니다. 이제 내 문제는, 어떤 사용자 입력을 기다리지 않고 영구적으로 mainloop을 실행하는 것입니다 ... – user2388767

+0

문제는 다른 이벤트를 처리 한 후 콜백 만 호출한다는 것입니다 (대략 말하기). 콜백을 타이머로 바꿨습니다. 그것은 그 문제를 해결해야합니다. 매 초마다 가장 작은 기간 인 아동을 폴링합니다. – ikegami