我正在阅读How do we capture CTRL ^ C - Perl Monks,但我似乎无法获得正确的信息来帮助解决我的问题。
事情是 - 我有一个无限循环,并且“多行”打印到终端(我知道我会被告知使用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$ _
显然,处理程序正在运行 - 但并不完全符合我期望的时间(或顺序)。有人可以澄清我如何解决这个问题,所以我得到了我想要的输出?
非常感谢任何答案, 干杯!
答案 0 :(得分: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$ _
嗯,希望这可以帮助某人,
干杯!