5

テキスト行を標準出力に単純に出力する単純な Perl スクリプトがあります。私が達成したいのは、このスクリプトの実行中に、私 (または他の誰か) がそのプロセスに停止するシグナルを発行した場合、そのシグナルをトラップして正常に終了することです。私が持っているコードは次のようになります

#!/usr/bin/perl -w

$| = 1;
use sigtrap 'handler' => \&sigtrap, 'HUP', 'INT','ABRT','QUIT','TERM';
while(1){
 print "Working...\n";
 sleep(2);
}
sub sigtrap(){
 print "Caught a signal\n";
 exit(1);
}

これは、実際にコマンド ラインから ctrl-c を押したときにうまく機能しますが、

kill -9 <pid>

それはただ死ぬ。終了する前に何かを実行するにはどうすればよいですか? 私の一般的な考えは、このフレームワークを使用して、メンテナンスまたは障害のためのサーバーの再起動により、このスクリプトがサーバー上で停止したときをキャプチャすることです。

よろしくお願いします

4

3 に答える 3

11

シグナル #9 (SIGKILL) はトラップできません。それがUnixの設計方法です。

ただし、メンテナンスのためにシャットダウンする場合、システムはその信号を送信しません。少なくとも、デーモンが正しく動作する場合。通常はTERMシグナルを送信します(または、より正確には、デーモン処理スクリプトが/etc/init.d行うことです)。タイムアウト後に正しくシャットダウンされなかったプロセスのみが SIGKILL を受け取ります。

したがって、目的は、TERM シグナルを正しく処理し/etc/init.d、システムがランレベルを変更するときに呼び出されるラッパー スクリプトを記述することです。

更新: init スクリプトにDaemon::Controlモジュールを使用できます。

于 2012-08-02T22:11:57.400 に答える
4

2 つの非常に異なるシグナルをプロセスに送信しています。Ctrl-Cコンソールを押すと、通常、プロセスにシグナルが送信されます。これは、コードから判断すると、キャッチされて処理されます。ただし、 は と呼ばれるシグナル番号 9 を明示的に送信します。これは、サービスを再定義できないシグナルの 1 つであり、このシグナルの配信は、カーネル自体によって行われるプロセスを常に即座に終了させます。TERMINTkill -9KILL

于 2012-08-02T21:51:17.753 に答える
3

As far as I know you can't capture kill -9. Try kill <pid> instead.

于 2012-08-02T22:02:14.030 に答える