5

我想在 Perl 中指定一个信号处理程序,但使用数字而不是名称。这可能以简洁的方式吗?杀戮缺乏对称性尤其突出。例如,而不是

$SIG{USR2} = \&myhandler;

我想说

$SIG{12} = \&myhandler;

我目前最好的方法是“使用 Config”并根据 perldoc perlipc 中的代码在 $Config{sig_name} 中四处寻找。这是冗长的,似乎不必要的复杂。

理由:我最近在两个案例中想要这个。

1:我是由一个错误的父进程启动的,他错误地设置了我关心忽略的信号,我只想将所有内容重置为默认值。例如http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=679630 目标将是一些简单而蛮力的东西,例如:

foreach my $i (1..32) { $SIG{$i} = 'DEFAULT'; }

2:我正在编写一个薄的、尽可能不可见的包装脚本。如果我包装的程序带有信号退出,我想退出相同的信号。但是,我捕获了一些信号,所以我需要清除我自己的信号处理程序以确保我真正退出而不是进入我的信号处理程序。我的目标是写一些像这样的简短内容:

$ret = system("./other-program");
$SIG{$ret & 127} = 'DEFAULT';
kill $ret & 127, $$;
4

2 回答 2

3

第一个问题:

use Config qw( %Config );

my @sig_name_by_num;
@sig_name_by_num[ split(' ', $Config{sig_num}) ] = split(' ', $Config{sig_name});

$SIG{$sig_name_by_num[12]} = \&handler;

第二个问题:

use Config qw( %Config );

$SIG{$_} = 'DEFAULT' for split ' ', $Config{sig_name};

-或者-

$SIG{$_} = 'DEFAULT' for keys %SIG;

-或者-

$_ = 'DEFAULT' for values %SIG;

第三个问题

use Config qw( %Config );

my @sig_name_by_num;
@sig_name_by_num[ split(' ', $Config{sig_num}) ] = split(' ', $Config{sig_name});

my $sig_num = $? & 0x7F;
$SIG{$sig_name_by_num[$sig_num]} = 'DEFAULT';
kill($sig_num => $$);
于 2012-07-24T01:33:34.520 回答
2

If you just want to set all signals at once, you don't need to know their numbers:

$SIG{$_} = 'DEFAULT' for keys %SIG;

Using $Config{sig_name}/$Config{sig_num} is the only portable way to map signal numbers to names, but a quick and dirty way that works on many Unix-y systems is

$sig_name = qx(kill -l $sig_num);

($sig_name will then have a trailing newline, so in practice you'd want to do something like

chomp($sig_name = qx(kill -l $sig_num));
($sig_name) = qx(kill -l $sig_num) =~ /(\S+)/;

)

That's not necessarily any more concise than using %Config, though, unless you turned it into a function.

sub sig_no { chomp(my ($sig_no = qx(kill -l $_[0])); $sig_no }

$SIG{ sig_no($ret & 127) } = 'DEFAULT';
...
于 2012-07-23T23:01:58.210 回答