Pearl catching Ctrl-C (sigint) in bash

I read How we fix CTRL ^ C - Perl Monks , but I can’t get the right information to help with my problem.

The fact is that I have an infinite loop and a "multi-line" printout on the terminal (I know that I will be asked to use ncurses ), but for short scripts it is more convenient for me to write a bunch of printf s). I would like to catch Ctrl-C in such a way that the script will end only after this multi-line printout is complete.

script (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" ; } ; } 

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

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

or

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

... however, I would like to get:

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

Obviously, the handlers are executed - but not quite in the timelines (or order) that I expect from them. Can someone clarify how I can fix this, so I get the output I want?

Thanks a lot in advance for any answers, Hooray!

+1
source share
1 answer

Hmmm ... it seems the solution was simpler than I thought :) In principle, the "captured output" check should start after printing the lines, but before the characters for "go three lines up" are printed; i.e. this 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 

... and then the output to Ctrl-C is as follows:

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

Well hopefully this can help someone
Hooray!

+1
source

All Articles