Я попытался собрать сценарий, который видел вместе, и использовал существующий сценарий, чтобы заставить что-то работать как сервис.Теперь у меня есть следующий сценарий pl и сценарии init.d / start / stop.
Они работают, но мне интересно, правильно ли я это сделал, потому что когда я запускаю службу и запускаю ее снова,он просто запустится снова и выдаст новый номер PID (это то, что я хочу? разве не должно быть сказано «уже запущен?»). Также я не понял, что делает «кеш» в STDIN и STDOUT.,И проверка файлов (файл, установленный в начале и в последнем цикле, проверяется на наличие более новой версии ... не уверен, что это делает). Здесь идет:
#!/usr/bin/perl
#use strict;
use POSIX;
use DateTime;
use Fcntl qw(:flock);
use File::CacheDir qw(cache_dir);
Log("Initializing...");
# Find and read config file
if (@ARGV != 1) {
print("Usage: miniserv.pl <config file>");
die;
}
if ($ARGV[0] =~ /^([a-z]:)?\//i) {
$config_file = $ARGV[0];
}
else {
print("NO CORRECT CONFIG FILE SPECIFIED");
die;
}
%config = &read_config_file($config_file);
Log("Initialized...");
Log("Loaded config file.");
my $file = $0;
my $age = -M $file;
Log("File - ".$file.", age - ".$age);
# Change dir to the server root
@roots = ( $config{'root'} );
for($i=0; defined($config{"extraroot_$i"}); $i++) {
push(@roots, $config{"extraroot_$i"});
}
chdir($roots[0]);
Log("Changed working directory: ".$roots[0]);
Status("Daemonizing...");
my $pid = fork;
if(!defined $pid)
{
LogError("Unable to fork : $!");
die;
}
if($pid)
{
Log("Parent process exiting, let the deamon (".$pid.") go...");
sleep 3;
exit;
}
POSIX::setsid;
if(-e $config{'pidfile'})
{
open(PID, "<".$config{'pidfile'});
my $runningpid = <PID>;
close PID;
unlink $config{'pidfile'};
while(-e "/proc/".$runningpid)
{
Status("Waiting for ".$runningpid." to exit...");
Log("Waiting for ".$runningpid." to exit...");
sleep 1;
}
}
open(PID, ">".$config{'pidfile'}) || die "Failed to create PID file $_[0] : $!";
print PID $$;
close PID;
Log("The deamon is now running...");
Status("Deamon running");
my $stdout = cache_dir({base_dir => $config{'root'}.'/cache', ttl => '1 day', filename => "STDOUT".$$});
my $stderr = cache_dir({base_dir => $config{'root'}.'/cache', ttl => '1 day', filename => "STDERR".$$});
Log("STDOUT : ".$stdout);
Log("STDERR : ".$stderr);
open STDIN, '/dev/null';
open STDOUT, '>>'.$stdout;
open STDERR, '>>'.$stderr;
while(1)
{
#### Code to be performed by the daemon
if($age - (-M $file))
{
Log("File modified, restarting");
open(FILE, $file ." |");
close(FILE);
last;
}
if(!-e $config{'pidfile'})
{
Log("Pid file doesn't exist, time go exit.");
last;
}
sleep 5;
}
sub Log
{
my $string = shift;
if($string)
{
my $time = DateTime->now();
if(open(LOG, ">>".$config{'logfile'}))
{
flock(LOG, LOCK_EX);
print LOG $$." [".$time->ymd." ".$time->hms."] - ".$string."\r\n";
close LOG;
}
}
}
sub LogError
{
my $string = shift;
if($string)
{
my $time = DateTime->now();
if(open(LOG, ">>".$config{'errorlog'}))
{
flock(LOG, LOCK_EX);
print LOG $$." [".$time->ymd." ".$time->hms."] - ".$string."\r\n";
close LOG;
}
}
}
sub Status
{
my $string = shift;
if($string)
{
$0 = "My Daemon- ".$string;
}
return $0;
}
# read_config_file(file)
# Reads the given config file, and returns a hash of values
sub read_config_file
{
local %rv;
if(-e $_[0])
{
open(CONF, $_[0]) || die "Failed to open config file $_[0] : $!";
while(<CONF>) {
s/\r|\n//g;
if (/^#/ || !/\S/) { next; }
/^([^=]+)=(.*)$/;
$name = $1; $val = $2;
$name =~ s/^\s+//g; $name =~ s/\s+$//g;
$val =~ s/^\s+//g; $val =~ s/\s+$//g;
$rv{$name} = $val;
}
close(CONF);
return %rv;
} else {
print("COULD NOT FIND CONFIG FILE");
die;
}
}
сценарий запуска
#!/bin/sh
echo Starting reliand server in /usr/libexec/reliand
trap '' 1
LANG=
export LANG
#PERLIO=:raw
unset PERLIO
export PERLIO
PERLLIB=/usr/libexec/reliand
export PERLLIB
exec '/usr/libexec/reliand/miniserv.pl' /etc/reliand/miniserv.conf
скрипт init.d
#!/bin/sh
# chkconfig: 235 99 10
# description: Start or stop the reliand server
#
### BEGIN INIT INFO
# Provides: reliand
# Required-Start: $network $syslog
# Required-Stop: $network
# Default-Start: 2 3 5
# Default-Stop: 0 1 6
# Description: Start or stop the reliand server
### END INIT INFO
start=/etc/reliand/start
stop=/etc/reliand/stop
lockfile=/var/lock/subsys/reliand
confFile=/etc/reliand/miniserv.conf
pidFile=/var/reliand/miniserv.pid
name='reliand'
case "$1" in
'start')
$start >/dev/null 2>&1 </dev/null
RETVAL=$?
if [ "$RETVAL" = "0" ]; then
touch $lockfile >/dev/null 2>&1
fi
;;
'stop')
$stop
RETVAL=$?
if [ "$RETVAL" = "0" ]; then
rm -f $lockfile
fi
pidfile=`grep "^pidfile=" $confFile | sed -e 's/pidfile=//g'`
if [ "$pidfile" = "" ]; then
pidfile=$pidFile
fi
rm -f $pidfile
;;
'status')
pidfile=`grep "^pidfile=" $confFile | sed -e 's/pidfile=//g'`
if [ "$pidfile" = "" ]; then
pidfile=$pidFile
fi
if [ -s $pidfile ]; then
pid=`cat $pidfile`
kill -0 $pid >/dev/null 2>&1
if [ "$?" = "0" ]; then
echo "$name (pid $pid) is running"
RETVAL=0
else
echo "$name is stopped"
RETVAL=1
fi
else
echo "$name is stopped"
RETVAL=1
fi
;;
'restart')
$stop ; $start
RETVAL=$?
;;
*)
echo "Usage: $0 { start | stop | restart }"
RETVAL=1
;;
esac
exit $RETVAL