5

Perlでシグナルハンドラーを指定したいのですが、名前ではなく番号を使用しています。これは簡潔な方法で可能ですか?キルとの対称性の欠如は特に際立っています。たとえば、代わりに

$SIG{USR2} = \&myhandler;

言いたいのですが

$SIG{12} = \&myhandler;

私が現時点で持っている最善の方法は、perldoc perlipcのコードに基づいて、「Configを使用」して$Config{sig_name}を調べてみることです。これは冗長で、不必要に複雑に見えます。

理論的根拠:最近、2つのケースでこれが必要になりました。

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;

2番目の質問:

use Config qw( %Config );

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

-また-

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

-また-

$_ = 'DEFAULT' for values %SIG;

3番目の質問

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

すべての信号を一度に設定したいだけの場合は、それらの番号を知る必要はありません。

$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';
...
于 2012-07-23T23:01:58.210 に答える