Perl:调用子例程而不是退出时,CRTL C被忽略

时间:2019-02-01 17:01:27

标签: perl

所以脚本是这样的:

use strict;
use warnings;
use Term::ReadLine;

$SIG{'INT'} = 'INT_handler';
sub INT_handler {
  print "[+] Abording\n";
  return home();
}

my $term = Term::ReadLine->new('Simple Perl calc');

sub home {

  my $prompt = "\$> ";
  my $OUT = $term->OUT || \*STDOUT;

  while ( defined ($_ = $term->readline($prompt)) ) {
    my $com = $_;
    print $com."\n";
    if ($com eq 'exit') {
        exit;
    }
  option(); # another subroutine when the input is transferred to
  }
}

home();

我能得到什么:

$>                                                                              
[+] Abording
$> # I pushed CRTL C but nothing shows                                                                             
$> # same here

我要实现的目标是能够不退出就进入home(),并使$SIG{'INT'}正常工作。

我尝试了其他方法(标签,使用if语句),但是会花费很长时间,因为输入需要较长的过程

1 个答案:

答案 0 :(得分:4)

您不应在信号处理程序中调用home()

只需设置一个标志即可检查输入循环。当$term->readline()返回时,由于它已被CTRL-C中断,请检查该标志是否已设置,对其进行重置并继续循环。

这是您更新的代码:

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

use Term::ReadLine;

$SIG{'INT'} = 'INT_handler';
my $interrupted;
sub INT_handler {
    $interrupted++;
}

my $term = Term::ReadLine->new('Simple Perl calc');

sub home {
    my $prompt = "\$> ";
    my $OUT = $term->OUT || \*STDOUT;

    while ( defined ($_ = $term->readline($prompt)) || $interrupted ) {
        if ($interrupted) {
            $interrupted = 0;
            print "\n[+] Aborting\n";
            next;
        }
        my $com = $_;
        print $com."\n";
        if ($com eq 'exit') {
            exit;
        }
    }
}

home();

exit 0;

测试输出:

$ perl dummy.pl
$> test
test
$> ^C

[+] Aborting
$> ^C

[+] Aborting
$> sdasd^C

[+] Aborting
$> exit
exit

注意::似乎仍然存在一个问题:您需要按回车键才能返回提示。可能与Term::Readline的工作方式有关。