2012-07-23 23 views
5

Tôi muốn chỉ định trình xử lý tín hiệu trong Perl, nhưng sử dụng số, chứ không phải tên. Điều này có thể theo một cách ngắn gọn không? Việc thiếu đối xứng với giết đặc biệt là gậy ra. Ví dụ, thay vìChỉ định trình xử lý tín hiệu Perl sử dụng số, chứ không phải tên

$SIG{USR2} = \&myhandler; 

Tôi muốn nói

$SIG{12} = \&myhandler; 

Điều tốt nhất tôi có vào lúc này là để "sử dụng Config" và poke xung quanh trong $ Config {} sig_name, dựa trên mã trong perldoc perlipc. Đây là tiết và dường như không cần thiết phức tạp.

Lý do: Gần đây tôi đã muốn điều này trong hai trường hợp.

1: Tôi đang được bắt đầu bởi một quá trình cha mẹ bị lỗi người đặt sai các tín hiệu mà tôi quan tâm để bỏ qua và tôi chỉ muốn đặt lại mọi thứ về mặc định. ví dụ http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=679630 Mục tiêu sẽ là một cái gì đó lực đơn giản và cao cấp brute như:

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

2: Tôi đang viết một mỏng, như-invisible-như-có thể kịch bản wrapper. Nếu chương trình tôi đang thoát khỏi một tín hiệu, tôi muốn thoát ra cùng với tín hiệu đó. Tuy nhiên, tôi nắm bắt một vài tín hiệu, vì vậy tôi cần phải xóa bộ xử lý tín hiệu của riêng mình để đảm bảo tôi thực sự thoát ra thay vì nhập trình xử lý tín hiệu của mình. Mục tiêu của tôi là viết một cái gì đó ngắn gọn như thế này:

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

Trả lời

2

Trước câu hỏi:

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; 

Thứ hai câu hỏi:

use Config qw(%Config); 

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

-hoặc-

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

-hoặc-

$_ = 'DEFAULT' for values %SIG; 

Câu hỏi thứ ba

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

Nếu bạn chỉ muốn đặt tất cả các tín hiệu cùng một lúc, bạn không cần phải biết số của họ:

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

Sử dụng $Config{sig_name}/$Config{sig_num} là chỉ cách cầm tay để lập bản đồ số tín hiệu đến tên, nhưng một cách nhanh chóng và dơ bẩn mà hoạt động trên nhiều hệ thống Unix-y là

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

($sig_name sau đó sẽ có một dòng mới trailing, vì vậy trong pra ctice bạn muốn làm điều gì đó như

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

)

Đó là không nhất thiết phải bất kỳ ngắn gọn hơn so với sử dụng %Config, tuy nhiên, trừ khi bạn biến nó thành một hàm.

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

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

Tôi mơ hồ của "chìa khóa% SIG" kỹ thuật. Một Perl gần đây (5.12.4) hợp lý đề nghị chuyển sang $ Config {sig_name}, và tôi tin rằng đó là vì trong lịch sử bạn không thể đếm được Perl để cư trú% SIG với các tín hiệu mà bạn chưa đặt. Nó xuất hiện trong thực tế rằng 5.12.4 trên Linux không cư trú các phím, nhưng nó không rõ ràng rằng đó là di động trên các hệ thống hoặc các phiên bản của Perl. –

Các vấn đề liên quan