ฉันมีสคริปต์ Perl ที่ฉันต้องการ daemonize โดยพื้นฐานแล้วสคริปต์ Perl นี้จะอ่านไดเรกทอรีทุก ๆ 30 วินาทีอ่านไฟล์ที่พบแล้วประมวลผลข้อมูล เพื่อให้ง่ายขึ้นที่นี่ให้พิจารณาสคริปต์ Perl ต่อไปนี้ (เรียกว่า synpipe_server มีลิงก์สัญลักษณ์ของสคริปต์นี้/usr/sbin/
):
#!/usr/bin/perl
use strict;
use warnings;
my $continue = 1;
$SIG{'TERM'} = sub { $continue = 0; print "Caught TERM signal\n"; };
$SIG{'INT'} = sub { $continue = 0; print "Caught INT signal\n"; };
my $i = 0;
while ($continue) {
#do stuff
print "Hello, I am running " . ++$i . "\n";
sleep 3;
}
ดังนั้นสคริปต์นี้พิมพ์บางสิ่งบางอย่างโดยทั่วไปทุก 3 วินาที
จากนั้นเมื่อฉันต้องการ daemonize สคริปต์นี้ฉันก็ใส่ bash script นี้ (หรือที่เรียกว่า synpipe_server) ใน/etc/init.d/
:
#!/bin/bash
# synpipe_server : This starts and stops synpipe_server
#
# chkconfig: 12345 12 88
# description: Monitors all production pipelines
# processname: synpipe_server
# pidfile: /var/run/synpipe_server.pid
# Source function library.
. /etc/rc.d/init.d/functions
pname="synpipe_server"
exe="/usr/sbin/synpipe_server"
pidfile="/var/run/${pname}.pid"
lockfile="/var/lock/subsys/${pname}"
[ -x $exe ] || exit 0
RETVAL=0
start() {
echo -n "Starting $pname : "
daemon ${exe}
RETVAL=$?
PID=$!
echo
[ $RETVAL -eq 0 ] && touch ${lockfile}
echo $PID > ${pidfile}
}
stop() {
echo -n "Shutting down $pname : "
killproc ${exe}
RETVAL=$?
echo
if [ $RETVAL -eq 0 ]; then
rm -f ${lockfile}
rm -f ${pidfile}
fi
}
restart() {
echo -n "Restarting $pname : "
stop
sleep 2
start
}
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status ${pname}
;;
restart)
restart
;;
*)
echo "Usage: $0 {start|stop|status|restart}"
;; esac
exit 0
ดังนั้น (ถ้าฉันเข้าใจ doc สำหรับ daemon เป็นอย่างดี) สคริปต์ Perl ควรทำงานในพื้นหลังและควรเปลี่ยนเส้นทางผลลัพธ์ไปที่/dev/null
ถ้าฉันเรียกใช้งาน:
service synpipe_server start
แต่นี่คือสิ่งที่ฉันได้รับแทน:
[root@master init.d]# service synpipe_server start
Starting synpipe_server : Hello, I am running 1
Hello, I am running 2
Hello, I am running 3
Hello, I am running 4
Caught INT signal
[ OK ]
[root@master init.d]#
ดังนั้นมันจึงเริ่มต้นสคริปต์ Perl แต่รันโดยไม่ต้องแยกออกจากเซสชันเทอร์มินัลปัจจุบันและฉันสามารถเห็นผลลัพธ์ที่พิมพ์ในคอนโซลของฉัน ... ซึ่งไม่ใช่สิ่งที่ฉันคาดหวัง นอกจากนี้ไฟล์ PID ว่างเปล่า (หรือด้วยการป้อนบรรทัดเท่านั้นไม่มีการส่งคืน pid โดยdaemon )
ไม่มีใครมีความคิดเกี่ยวกับสิ่งที่ฉันทำผิดหรือเปล่า?
แก้ไข: บางทีฉันควรจะบอกว่าฉันอยู่ในเครื่อง Red Hat
Scientific Linux SL release 5.4 (Boron)
มันจะทำงานได้ไหมถ้าแทนที่จะใช้ฟังก์ชั่น daemon ฉันจะใช้สิ่งที่ชอบ:
nohup ${exe} >/dev/null 2>&1 &
ในสคริปต์ init หรือไม่
daemon
และkillproc
แทน