2011-11-14 10 views
21

मेरे पास एक पर्ल स्क्रिप्ट है जिसे मैं डिमन करना चाहता हूं। असल में यह perl स्क्रिप्ट प्रत्येक 30 सेकंड में एक निर्देशिका पढ़ेगी, जो फाइलें पाती हैं उन्हें पढ़ें और फिर डेटा को संसाधित करें।एक /etc/init.d स्क्रिप्ट में डेमॉन पर कॉल अवरुद्ध है, पृष्ठभूमि में नहीं चल रहा है

#!/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 सेकंड प्रिंट: यह सरल यहाँ निम्नलिखित पर्ल स्क्रिप्ट पर विचार रखने के लिए (synpipe_server कहा जाता है, वहाँ /usr/sbin/ में इस स्क्रिप्ट का एक प्रतीकात्मक कड़ी है)।

फिर, के रूप में मैं इस स्क्रिप्ट daemonize करना चाहते हैं, मैं भी इस पार्टी स्क्रिप्ट (भी बुलाया 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 

तो, (अच्छी तरह से डेमॉन के लिए डॉक समझा कि मेरे पास) पर्ल स्क्रिप्ट पृष्ठभूमि में चलाने चाहिए और उत्पादन /dev/null पर पुनः निर्देशित किया जाना चाहिए अगर मैं निष्पादित करें:

service synpipe_server start 

लेकिन यहाँ मैं क्या बजाय मिलता है:

[[email protected] 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 ] 
[[email protected] init.d]# 

तो यह पर्ल स्क्रिप्ट शुरू करता है लेकिन इसे मौजूदा टर्मिनल सत्र से अलग किए बिना चलाता है, और मैं अपने कंसोल में मुद्रित आउटपुट देख सकता हूं ... जो वास्तव में मैं उम्मीद नहीं कर रहा था। इसके अलावा, पीआईडी ​​फ़ाइल खाली है (या केवल लाइन फीड के साथ, डेमॉन द्वारा कोई भी पिड वापस नहीं किया गया है)।

क्या किसी को भी कोई विचार है कि मैं क्या गलत कर रहा हूं?

संपादित करें: शायद मुझे यह कहना चाहिए कि मैं एक Red Hat मशीन पर हूं।

Scientific Linux SL release 5.4 (Boron) 

धन्यवाद, टोनी

+3

के बजाय परिवर्तन के लिए मतदान करने के लिए एक डेमॉन लेखन, आप http://en.wikipedia.org/wiki/Inotify inotify इस्तेमाल कर सकते हैं आपको सूचित करना है जब एक परिवर्तन हुआ है। कोड के लिए कोड करना अधिक आसान है, और अधिक तेज़ अपडेट देख सकते हैं। इसके साथ बात करने के लिए कई सीपीएएन मॉड्यूल हैं। http://search.cpan.org/search?query=inotify&mode=all – Schwern

+0

धन्यवाद, यह उपयोगी जानकारी है, मैं निश्चित रूप से इनोटिफी पर एक नज़र डालेगा। – tony

+0

@Schwern: यह इस तथ्य को नहीं बदलेगा कि पृष्ठभूमि में एक डिमन चलाने के लिए मुझे अधिसूचना अधिसूचनाओं की प्रतीक्षा करनी है, नहीं ?? – tony

उत्तर

15

मैं अंत में फिर से लिखा था बैश इनिट स्क्रिप्ट में फ़ंक्शन प्रारंभ करें, और मैंका उपयोग नहीं कर रहा हूंअब और।

start() { 
    echo -n "Starting $pname : " 
    #daemon ${exe} # Not working ... 
    if [ -s ${pidfile} ]; then 
     RETVAL=1 
     echo -n "Already running !" && warning 
     echo 
    else 
     nohup ${exe} >/dev/null 2>&1 & 
     RETVAL=$? 
     PID=$! 
     [ $RETVAL -eq 0 ] && touch ${lockfile} && success || failure 
     echo 
     echo $PID > ${pidfile} 
    fi 
} 

मैं जांचता हूं कि पीआईडी ​​फ़ाइल पहले से मौजूद नहीं है (यदि हां, तो बस एक चेतावनी लिखें)। यदि नहीं, तो मैं

nohup ${exe} >/dev/null 2>&1 & 

स्क्रिप्ट प्रारंभ करने के लिए उपयोग करता हूं।

मुझे नहीं पता कि यह इस तरह से सुरक्षित है (?) लेकिन यह काम करता है।

+2

मैंने कुछ समान उपयोग किया, लेकिन स्क्रिप्ट शुरू होने पर दिखाए गए आउटपुट प्रदान करने के लिए नोहप के साथ 'डेमन' का उपयोग किया गया। यह एक दृश्य क्यू का अधिक है, क्योंकि कुछ भी नहीं, चूंकि [ओके] संदेश हमेशा तक ठीक से वापस आ जाएगा जब तक नोहुप चलाया जाता है: 'डिमन" नोहुप $ {exe}>/dev/null 2> और 1 और "' एक उदाहरण के रूप में । – Rohaq

+0

टोनी, जब आपका खोल समाप्त हो जाता है तो यह डिमन मर जाएगा? या नोहुप इसे रोकता है? – Mark

+0

हां, जब खोल समाप्त हो जाता है, नोहुप द्वारा बनाई गई प्रक्रिया जीवित बनी हुई है। – tony

0

man daemon सही सिंटैक्स के अनुसार है

daemon [options] -- [command] [command args] 

आपका init स्क्रिप्ट स्टार्टअप की तरह कुछ चलाना चाहिए:

daemon --pidfile ${pidfile} -- ${exe} 
+3

धन्यवाद yko, लेकिन ऐसा इसलिए नहीं है क्योंकि मेरा 'डेमन' उपयोग कहता है: 'डेमन [+/- nicelevel] {program}'। शायद हमारे पास एक ही संस्करण नहीं है। – tony

+0

@tony क्या आप कमांड उपयोग समस्या हल करने में सक्षम थे? –

+0

@tony मैंने स्थापित किया [libslack से डेमन] (http://libslack.org/daemon/#download) –

0

जैसा कि here कहा गया है, ऐसा लगता है कि प्रक्रिया & का उपयोग कर पृष्ठभूमि में भेजी जानी चाहिए। डेमॉन आपके लिए यह नहीं करता है।

1

प्रक्रिया को डिमन करने का सही तरीका यह है कि यह टर्मिनल से से अलग हो गया है। इस प्रकार, अधिकांश बड़े सॉफ़्टवेयर सूट इसे करते हैं, उदाहरण के लिए, apache

daemon के पीछे तर्क नहीं कर रही है कि तुम क्या इसके नाम से उम्मीद होती है, और कैसे बनाने के लिए पृष्ठभूमि में एक यूनिक्स प्रक्रिया को अलग, खंड 1.7 में here पाया जा सकता है मैं अपने कार्यक्रम के एक डेमॉन की तरह काम करने के लिए कैसे मिलता है?

आप पृष्ठभूमि में एक कार्यक्रम लागू इन लंबे समय से चल कार्यक्रमों के लिए वास्तव में पर्याप्त नहीं है; जो टर्मिनल सत्र से प्रक्रिया को सही ढंग से अलग नहीं करता है। इसके अलावा, डेमन्स शुरू करने का पारंपरिक तरीका मैन्युअल रूप से या आरसी स्क्रिप्ट से आदेश जारी करना है; डेमॉन से पृष्ठभूमि में खुद डालने की उम्मीद है।

इस विषय पर आगे पढ़ने के लिए: What's the difference between nohup and a daemon?

संबंधित मुद्दे