Perl で、スクリプトをデーモン化するのはそんなに難しくない。
Proc::Daemon というモジュールを使えば簡単にできるのだが、それには小さなフレームワークに沿ってスクリプトを書かねばならない。次のサンプルに空のフレームワークを示したので、既存のスクリプトがある場合にはこれに沿って自分のスクリプトを少々改造すればよい。基本的には action サブルーチンにロジックを書けばいいようになっている。
使用するモジュール
use Proc::Daemon;
#/usr/bin/perl -w
use Proc::Daemon;
our $DAEMON = 1; # デーモンにするか?: 1(オン) / 0 (オフ)
our $SLEEP_INTERVAL = 60; # スリープの間隔(秒)
&init;
&run;
sub action {
# ここにロジックを書く
return 1;
}
sub interrupt {
eval{ close(XXXXX); }; # グローバルで開いているファイルがあれば、閉じる
my $sig = shift;
setpgrp; # I *am* the leader
$SIG{$sig} = 'IGNORE';
kill $sig, 0; # death to all-comers
die "killed by $sig";
exit(0);
}
sub init {
$SIG{INT} = 'interrupt'; # Ctrl-C が押された場合
$SIG{HUP} = 'interrupt'; # HUP シグナルが送られた場合
$SIG{QUIT} = 'interrupt'; # QUIT シグナルが送られた場合
$SIG{KILL} = 'interrupt'; # KILL シグナルが送られた場合
$SIG{TERM} = 'interrupt'; # TERM シグナルが送られた場合
<font color="red">Proc::Daemon::Init</font> if $DAEMON; # as a daemon
}
sub run {
while(1) {
# SLEEP_INTERVAL ごとに action を呼び出す
&action;
sleep($SLEEP_INTERVAL);
}
}
1;
以下、サンプルの説明である。
- このスクリプトのフレームワークには init、run、interrupt、action といった 4つのサブルーチンがあり、決め打ちのサブルーチンは基本的に init と run である。interrupt と action サブルーチンは、自分で書く部分である。
- init では $SIG 変数(この名前は決め打ちだから変更してはいけない) で、デーモンが様々な状況で中断されたときに呼び出されるサブルーチンを登録 、設定している(←割り込み処理のこと)。 ここではどんな状況でも interrupt サブルーチンを呼ぶようにしたが、各状況でそれぞれ違う処理に飛ばしたいときは、それぞれの状況で中断されたときに呼び出されるサブルーチンを書き、各 $SIG{...} によって、そのサブルーチンに飛ばせばよい。
- init の中に Proc::Daemon::Init...; という行があるが、このたった 1行がこのスクリプトをデーモン化するおまじないである。
- このスクリプトは続いて run を呼ぶ。この run の中身は while (1) { ... } とした無限ループである。この無限ループの中ではsleep 関数を呼んでいて、何か処理をしたあとに $SLEEP_INTERVAL 秒だけこのスクリプトに寝てもらうことになっている。初めてこれを見た人は、デーモンといっても、なんだ結局はこんなものか(なよなょ)・・・と、落胆するであろうが、そういうものである(スレッドとプロセスの違いはあるけれども、Java の runnable インターフェイスだって同じように書くはずだ)。
- デーモンが寝ている間隔は、$SLEEP_INTERVAL でその秒数を定義しているが、スクリプトの中で何かの処理によってこの値を変化させてもよい。つまりスリープ間隔は動的にできる。
- run の無限ループの中では action サブルーチンを呼ぶようになっている。この action というサブルーチン名は、私が勝手につけたものだから自由に変更してよい。その意味だとここに挙げているサブルーチン名 init、run、interrupt、action の 4つは各人が変更してよい。
- 基本的に action サブルーチンの中に、このスクリプトが処理したいこと(カッコよく言えばビジネスロジック)を書く。たとえば、LWP でウェブにアクセスして情報を取ってくるような処理である。
トラックバック URL:
https://perltips.twinkle.cc/trackback/113