【问题标题】:Name of signal number 2信号编号 2 的名称
【发布时间】:2015-04-25 19:58:28
【问题描述】:

我想知道是否有定义system 调用返回的信号编号名称的模块或编译指示?例如:

use feature qw(say);
use strict;
use warnings;

my $cmd = 'sleep 10';
my $res = system $cmd;
my $signal = $res & 127;
if ( $res == -1 ) {
    die "Failed to execute: $!\n";
}
elsif ( $signal == 2 ) {
    say " Aborted by user.";
}
elsif ( $signal ) {
    printf " Command '%s' Died with signal %d, %s coredump.\n",
      $cmd, $signal, ( $? & 128 ) ? 'with' : 'without';
}

我认为对于代码维护,最好使用$signal == SIG_ABRT..之类的东西,而不是$signal == 2

【问题讨论】:

    标签: perl


    【解决方案1】:

    有几种方法可以做到这一点。您已经看到了一种使用POSIX 的方法,我通常会避免使用这种方法,因为默认情况下它会将大量 个符号(近六百个)导入到当前包中。即使您通过编写将其限制为您需要的名称

    use POSIX ':signal_h';
    

    仍有大约 50 个名称被导入。使用这个模块来发现一个信号的名称也是一个反复试验的问题,给定它的编号

    您还可以使用 Config 模块构建您的 Perl 所使用的信号表,该模块在 $Config{sig_name}$Config{sig_num} 中导出信号名称及其对应编号的列表。

    use strict;
    use warnings;
    
    use Config '%Config';
    
    my @sig_names;
    @sig_names[ split ' ', $Config{sig_num} ] = split ' ', $Config{sig_name};
    
    printf "Signal number 2 is %s\n", $sig_names[2];
    

    输出

    Signal number 2 is INT
    

    或者您可以使用 IPC::Signal 模块,它可以方便地包装所有这些

    use strict;
    use warnings;
    
    use IPC::Signal 'sig_name';
    
    printf "Signal number 2 is %s\n", sig_name(2);
    

    输出

    Signal number 2 is INT
    

    【讨论】:

    • use POSIX (); my $sigint = POSIX::SIGINT; 怎么样。那也应该避免导入所有符号?
    • @HåkonHægland:这可行,但您仍然需要检查所有 POSIX::SIGXXX 值才能找到您要查找的值
    【解决方案2】:

    是的,这是在POSIX 模块中定义的:

    % perl -e 'use POSIX; printf "%s\n", SIGABRT;'
    6
    

    【讨论】:

    • 谢谢.. 我想那是 SIGINT 吗?
    • 正确,SIGINT 是 2 。在 Linux 中,您可以使用 kill -l 列出此内容。
    猜你喜欢
    • 2015-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-19
    • 1970-01-01
    • 1970-01-01
    • 2012-10-20
    相关资源
    最近更新 更多