2

CTRL ^ C --Perl Monksをキャプチャする方法を読んでいますが、問題を解決するための適切な情報を取得できないようです。

重要なのは、無限ループがあり、ターミナルへの「マルチライン」プリントアウトです(代わりに使用するように指示されることは承知していますが、短いスクリプトの場合は、 sのncurses束を書く方が快適ですprintf)。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$ _

明らかに、ハンドラーは実行されていますが、期待するタイミング(または順序)ではありません。誰かがこれを修正する方法を明確にできるので、必要な出力を取得できますか?

よろしくお願いします。

4

1 に答える 1

1

うーん...解決策は思ったより簡単だったようです:)基本的に、「トラップされた出口」のチェックは、行が印刷された後、「3行上に行く」の文字が印刷される前に実行する必要があります。つまり、そのセクションは次のようになります。

  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$  _

さて、これが誰かを助けるかもしれないことを願っています、
乾杯!

于 2011-09-22T09:24:27.403 に答える