Perl在bash中捕获Ctrl-C(sigint) [英] Perl trapping Ctrl-C (sigint) in bash

查看:304
本文介绍了Perl在bash中捕获Ctrl-C(sigint)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读我们如何捕获CTRL ^ C-Perl僧侣,但是我似乎无法获得正确的信息来解决我的问题.

I'm reading How do we capture CTRL ^ C - Perl Monks, but I cannot seem to get the right info to help with my problem.

问题是-我有一个无限循环,并且在终端显示了多行"打印输出(我知道我会被告知使用ncurses-但对于简短的脚本,我会更自在写一堆printf s ).我想以这种方式捕获Ctrl-C,以使脚本仅在完成多行打印输出后 终止.

The thing is - I have an infinite loop, and 'multiline' printout to terminal (I'm aware I'll be told to use ncurses instead - but for short scripts, I'm more comfortable writing a bunch of printfs). I'd like to trap Ctrl-C in such a way, that the script will terminate only after this multiline printout has finished.

脚本为(Ubuntu Linux 11.04):

The script is (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,我将得到类似的信息(请注意,_指示脚本终止后终端光标的位置):

Now, if I run this, and I press Ctrl-C, I either get something like this (note, the _ indicates position of terminal cursor after script has terminated):

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

或:

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

...但是,我想得到:

... however, I'd like to get:

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

很显然,处理程序正在运行-但是我期望它们的时间安排(或顺序)不够.有人可以澄清如何解决此问题,以便获得所需的输出吗?

Obviously, handlers are running - but not quite in the timing (or order) I expect them to. Can someone clarify how do I fix this, so I get the output I want?

在此先感谢您的回答, 干杯!

Many thanks in advance for any answers, Cheers!

推荐答案

Hmmm ...似乎解决方案比我想象的要容易:)基本上,对陷阱出口"的检查应在打印行之后执行-但在打印出向上三行"的字符;也就是说,该部分应为:

Hmmm... seems solution was easier than I thought :) Basically, the check for "trapped exit" should run after the lines are printed - but before the characters for "go three lines up" are printed; that is, that section should be:

  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上的输出似乎是:

... and then the output upon Ctrl-C seems to be like:

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

好吧,希望这可以对某人有所帮助,
干杯!

Well, hope this may help someone,
Cheers!

这篇关于Perl在bash中捕获Ctrl-C(sigint)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆