2011-09-22 127 views
1

我在閱讀How do we capture CTRL^C - Perl Monks,但我似乎無法獲得正確的信息來幫助解決我的問題。Perl陷阱Ctrl-C(sigint)在bash中

事情是 - 我有一個無限循環,並且'多行'打印輸出到終端(我知道我會被告知使用ncurses而不是 - 但對於簡短腳本,我更舒適寫一堆printf s)。我想以這種方式捕捉Ctrl-C,在這個多行打印輸出完成後,腳本將僅終止

的腳本(Ubuntu Linux操作系統11.04):

#!/usr/bin/env perl 
use strict; 
use warnings; 

use Time::HiRes; 

binmode(STDIN); # just in case 
binmode(STDOUT); # just in case 


# to properly capture Ctrl-C - so we have all lines printed out 
# unfortunately, none of this works: 
my $toexit = 0; 
$SIG{'INT'} = sub {print "EEEEE"; $toexit=1; }; 
#~ $SIG{INT} = sub {print "EEEEE"; $toexit=1; }; 
#~ sub REAPER { # http://www.perlmonks.org/?node_id=436492 
     #~ my $waitedpid = wait; 
     #~ # loathe sysV: it makes us not only reinstate 
     #~ # the handler, but place it after the wait 
     #~ $SIG{CHLD} = \&REAPER; 
     #~ print "OOOOO"; 
    #~ } 
#~ $SIG{CHLD} = \&REAPER; 
#~ $SIG{'INT'} = 'IGNORE'; 



# main 

# http://stackoverflow.com/questions/14118/how-can-i-test-stdin-without-blocking-in-perl 
use IO::Select; 
my $fsin = IO::Select->new(); 
$fsin->add(\*STDIN); 


my ($cnt, $string); 
$cnt=0; 
$string = ""; 

while (1) { 
    $string = ""; # also, re-initialize 
    if ($fsin->can_read(0)) { # 0 timeout 
    $string = <STDIN>; 
    } 
    $cnt += length($string); 

    printf "cnt: %10d\n", $cnt; 
    printf "cntA: %10d\n", $cnt+1; 
    printf "cntB: %10d\n", $cnt+2; 
    print "\033[3A"; # in bash - go three lines up 
    print "\033[1;35m"; # in bash - add some color 
    if ($toexit) { die "Exiting\n" ; } ; 
} 

現在,如果我跑這一點,我按下Ctrl-C,我要麼得到這樣的事情(說明,_顯示終端的位置遊標腳本已經終止後):

MYPROMPT$ ./test.pl 
cnEEEEEcnt:   0 
MYPROMPT$ _ 
cntB:   2 
Exiting 

或:

MYPROMPT$ ./test.pl 
cncnt:   0 
MYPROMPT$ _ 
cntB:   2 
Exiting 

...但是,我想獲得:

MYPROMPT$ ./test.pl 
cncnt:   0 
cntA:   1 
cntB:   2 
Exiting 
MYPROMPT$ _ 

顯然,處理程序正在運行 - 但並不完全在時序(或訂單),我希望他們。有人可以澄清我如何解決這個問題,所以我得到我想要的輸出?

非常感謝任何答案, 乾杯!

+1

我不確定如果在控制流中出現的唯一位置恰好在將光標移回頂端的代碼之後,您可能期望在三個「cnt」行下面有「退出」。 –

+0

感謝您的評論@JB - 剛剛意識到這是問題:)乾杯! – sdaau

回答

1

嗯...似乎解決方案比我想象的要容易:)基本上,「被困退出」的檢查應該在打印行後運行 - 但在打印「去三行」字符之前;也就是說,部分應該是:

printf "cnt: %10d\n", $cnt; 
    printf "cntA: %10d\n", $cnt+1; 
    printf "cntB: %10d\n", $cnt+2; 
    if ($toexit) { die "Exiting\n" ; } ; 
    print "\033[3A"; # in bash - go three lines up 
    print "\033[1;35m"; # in bash - add some color 

...然後在按Ctrl-C的輸出似乎是這樣的:

MYPROMPT$ ./test.pl 
cnt:   0 
^CcntA:   1 
cntB:   2 
Exiting 
MYPROMPT$ _ 

好了,希望這可以幫助別人,
乾杯!