perl术语:: readline :: gnu信号处理困难



我正在使用term :: readline :: gnu,并且遇到了信号处理问题。给定下面的脚本和发送到脚本的术语信号,直到按下按下Enter键。使用term :: readline:perl这不会发生。

我已经阅读了该术语:: readline :: gnu有其自己的内部信号处理程序,但是坦率地说,我对如何与他们一起工作感到不知所措。

我已经回顾了http://search.cpan.org/~hayashi/term-readline-gnu-1.20/gnu.pm#term:: readline:: gnu_variables尝试将RL_CATCH_SIGNALS变量设置为0,但是DIDN't帮助。理想情况下,我想与GNU信号处理程序一起工作,但我也会安定为禁用它们。

绝对具体,我需要一词处理程序在接收信号后触发而不是等待按下Enter键。

任何帮助或建议肯定会受到赞赏!

#!/usr/bin/perl
use strict;
use warnings;
use Term::ReadLine;
$SIG{TERM} = sub { print "I got a TERMn"; exit; };
my $term = Term::ReadLine->new('Term1');
$term->ornaments(0);
my $prompt = 'cmd> ';
while ( defined (my $cmd = $term->readline($prompt)) ) {
    $term->addhistory($cmd) if $cmd !~ /S||n/;
    chomp($cmd);
    if ($cmd =~ /^help$/) {
        print "Help Menun";
    }
    else {
        print "Nothingn";
    }
}

这是由于Perl对信号的默认偏执处理 - 幕后,Perl在启动readline呼叫之前阻止Sigterm并在完成后将其恢复。有关详细信息,请参见Perlipc的延期信号。

Term::ReadLine::Perl使用Perl的IO,它知道这些问题并处理它们,因此您不会看到此错误。Term::ReadLine::Gnu使用C库,因此您可以。

您可以使用两种方法之一来解决此问题:

  1. 在运行脚本之前,将环境变量perl_signals设置为 unsafe,如:

    bash$ PERL_SIGNALS=unsafe perl readline-test.pl
    

    注意,BEGIN { $ENV{PERL_SIGNALS} = "unsafe"; }还不够,需要在Perl本身开始之前设置它。

  2. 使用POSIX信号功能:

    #~ $SIG{TERM} = sub { print "I got a TERMn"; exit; };
    use POSIX;
    sigaction SIGTERM, new POSIX::SigAction sub { print "I got a TERMn"; exit; };
    

    上面的两个似乎都在Linux中起作用;无法代表Windows或其他Unices。另外,以上两个都有风险 - 有关详细信息,请参见Perlipc。

最新更新