2012-07-23 7 views
5

Ich möchte einen Signalhandler in Perl angeben, aber die Nummer verwenden, nicht den Namen. Ist das in knapper Form möglich? Besonders hervorzuheben ist der Mangel an Symmetrie bei der Abtötung. Zum Beispiel, stattGeben Sie den Perl-Signalhandler unter Verwendung der Nummer und nicht des Namens an.

$SIG{USR2} = \&myhandler; 

Ich mag würde

$SIG{12} = \&myhandler; 

Das Beste, was ich im Moment sagen ist, "Config" und schnüffeln in $ Config {sig_name}, basierend auf der Code in perldoc perlipc. Dies ist ausführlich und scheint unnötig kompliziert.

Begründung: Ich wollte das in letzter Zeit in zwei Fällen.

1: Ich werde von einem fehlerhaften Elternprozess gestartet, der Signale falsch setzt, die ich ignorieren möchte, und ich möchte einfach alles auf den Standard zurücksetzen.

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

2: Ich schreibe einen dünnen, als unsichtbare-as-möglich Wrapper-Skript zB http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=679630 Das Ziel wäre etwas einfach und Brute-Force-ähnliches sein. Wenn das Programm, das ich umschließe, mit einem Signal beendet wird, möchte ich mit demselben Signal aufhören. Ich nehme jedoch ein paar Signale auf, deshalb muss ich meinen eigenen Signal-Handler löschen, um sicherzustellen, dass ich tatsächlich austrete, anstatt meinen Signal-Handler zu betreten. Mein Ziel ist es etwas kurz wie folgt zu schreiben:

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

Antwort

2

Erste Frage:

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; 

Zweite Frage:

use Config qw(%Config); 

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

-oder

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

-oder

$_ = 'DEFAULT' for values %SIG; 

Dritte Frage

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 => $$); 
2

Wenn Sie nur festlegen möchten alle Signale auf einmal, Sie müssen nicht um ihre Zahl wissen:

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

$Config{sig_name}/$Config{sig_num} erst der Einsatz von tragbare Art und Weise Signalnummern zu den Namen auf der Karte, aber eine schnelle und schmutzige Art und Weise, die auf vielen Unix-y-Systemen funktioniert, ist

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

($sig_name wird dann eine Hinter newline, also in pra ctice Sie so etwas wie

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

)

Das ist nicht unbedingt mehr prägnant als %Config verwenden, obwohl tun wollen würde, wenn Sie es in eine Funktion eingeschaltet.

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

$SIG{ sig_no($ret & 127) } = 'DEFAULT'; 
... 
+0

Ich bin zweifelhaft der "Schlüssel% SIG" -Technik. Ein einigermaßen aktuelles Perl (5.12.4) empfiehlt, zu $ ​​Config {sig_name} zu gehen, und ich glaube, das liegt daran, dass Sie in der Vergangenheit nicht darauf zählen konnten, dass% SIG mit Signalen gefüllt wurde, die Sie nicht selbst gesetzt hatten. Es scheint in der Praxis so zu sein, dass 5.12.4 unter Linux die Schlüssel auffüllt, aber es ist nicht klar, dass das über Systeme oder Versionen von Perl übertragbar ist. –

Verwandte Themen