我想在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, $$;
答案 0 :(得分: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};
-OR -
$SIG{$_} = 'DEFAULT' for keys %SIG;
-OR -
$_ = '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 => $$);
答案 1 :(得分:2)
如果您只想一次设置所有信号,则无需知道其编号:
$SIG{$_} = 'DEFAULT' for keys %SIG;
使用$Config{sig_name}/$Config{sig_num}
是将信号编号映射到名称的唯一可移植方式,但是在许多Unix-y系统上运行的快速而肮脏的方式是
$sig_name = qx(kill -l $sig_num);
($sig_name
将有一个尾随换行符,所以在实践中你想要做类似的事情
chomp($sig_name = qx(kill -l $sig_num));
($sig_name) = qx(kill -l $sig_num) =~ /(\S+)/;
)
除非你把它变成一个函数,否则不一定比使用%Config
更简洁。
sub sig_no { chomp(my ($sig_no = qx(kill -l $_[0])); $sig_no }
$SIG{ sig_no($ret & 127) } = 'DEFAULT';
...