【问题标题】:Perl Term::ReadLine::Gnu Signal Handling DifficultiesPerl Term::ReadLine::Gnu 信号处理困难
【发布时间】:2012-10-30 06:06:31
【问题描述】:

我正在使用 Term::ReadLine::Gnu 并且遇到了信号处理问题。给定下面的脚本和发送到脚本的 TERM 信号,直到 按下回车键后,才会触发 TERM 信号的处理程序。使用 Term::ReadLine:Perl 不会发生这种情况。

我读过 Term::ReadLine::Gnu 有自己的内部信号处理程序,但坦率地说,我不知道如何使用它们。

我已经查看了http://search.cpan.org/~hayashi/Term-ReadLine-Gnu-1.20/Gnu.pm#Term::ReadLine::Gnu_Variables,尝试将 rl_catch_signals 变量设置为 0,但这没有帮助。理想情况下,我希望使用 Gnu 信号处理程序,但我也会满足于禁用它们。

确切地说,我需要在收到信号后触发 TERM 处理程序,而不是等待按下回车键。

非常感谢任何帮助或建议!

#!/usr/bin/perl

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

$SIG{TERM} = sub { print "I got a TERM\n"; 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 Menu\n";
    }
    else {
        print "Nothing\n";
    }
}

【问题讨论】:

  • 我想知道这是否是一个缓冲问题。试试这个答案的解决方案:stackoverflow.com/a/7603502/1791055
  • /\S||\n/ 应该做什么? :-) (与您的实际问题无关,我只是注意到了。)请注意,由于您的两个管道之间没有任何内容,因此正则表达式将匹配任何内容,因此 !~ 将始终为假。
  • ysth 帮助我在另一篇帖子stackoverflow.com/questions/13332908/… 中回答了这个问题,事实证明这完全是多余的,因为 T:R:G 默认会添加历史记录。我会删除它。
  • titanofold - 感谢您的链接。当然很有趣(我会试一试),但我不确定这是否能解决这个问题。我认为这更多是关于使用 T:R:G 的内部信号处理。

标签: perl readline signal-handling


【解决方案1】:

这是由于 perl 对信号的默认偏执处理 - 在幕后,perl 在开始 readline 调用之前阻止 SIGTERM 并在完成时恢复它。详情请见Deferred Signals in perlipc

Term::ReadLine::Perl 使用 perl 的 IO,它知道这些问题并处理它们,所以你看不到这个 bug。 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 TERM\n"; exit; };
    use POSIX;
    sigaction SIGTERM, new POSIX::SigAction sub { print "I got a TERM\n"; exit; };
    

    以上两种方法似乎都适用于 Linux;不能代表 Windows 或其他 unices。此外,上述两种情况都存在风险 - 有关详细信息,请参阅 perlipc。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-02
    • 2017-05-04
    • 1970-01-01
    相关资源
    最近更新 更多