목차

Unix Daemons in Perl

Now that we understand the basic attributes of a daemon, let's put the pieces together into a simple Perl program:

Simple Daemon: Listing 1

use POSIX qw(setsid);

chdir '/'                 or die "Can't chdir to /: $!";
umask 0;
open STDIN, '/dev/null'   or die "Can't read /dev/null: $!";
#open STDOUT, '>/dev/null' or die "Can't write to /dev/null: $!";
open STDERR, '>/dev/null' or die "Can't write to /dev/null: $!";
defined(my $pid = fork)   or die "Can't fork: $!";
exit if $pid;
setsid                    or die "Can't start a new session: $!";

while(1) {
   sleep(5);
   print "Hello...\n";
}

The example above is a simple daemon that will print Hello… to the console every five seconds. Also, notice that one line of the program has been commented out. Removing the comment will suppress the hello message by sending all standard output to /dev/null. Also notice that we included the POSIX library and explicitly imported the setsid function since this function is part of the POSIX library, not a built-in Perl function. One other little critical piece is the while(1) { } loop with sleep(5) inside. The loop ensures that the script will run indefinitely. The sleep function sets the number of seconds between each iteration in the loop. The main body of your code will site inside this while loop.

Web Mirror: Listing 2

For example, let's say we need a daemon that mirrors a Web page on a pre-production server. When the file gets updated, it is synced with the production server. We can easily whip up a script that does this by using the mirror method of the LWP::Simple module. Below is a script that implements this functionality.

# load required modules
use strict;
use POSIX qw(setsid);
use LWP::Simple;

# set costants
my $URL     = 'http://www.webreference.com/perl/';
my $FILE    = '/tmp/motherofperl.html';

# flush the buffer
$| = 1;

# daemonize the program
&daemonize;

# our infinite loop
while(1) {
    # mirror the file
    mirror($URL,$FILE);
   
    # wait for 60 seconds
    sleep(60);
}

sub daemonize {
    chdir '/'                 or die "Can't chdir to /: $!";
    open STDIN, '/dev/null'   or die "Can't read /dev/null: $!";
    open STDOUT, '>>/dev/null' or die "Can't write to /dev/null: $!";
    open STDERR, '>>/dev/null' or die "Can't write to /dev/null: $!";
    defined(my $pid = fork)   or die "Can't fork: $!";
    exit if $pid;
    setsid                    or die "Can't start a new session: $!";
    umask 0;
}