बैश: बाल प्रक्रियाओं के साथ डेमॉन शुरू करें

सभी को अच्छा मूड!
मैंने इस लेख को यहाँ पढ़ा, और मैंने चेकर्स को खुद से थोड़ा चुनने का फैसला किया और अपने लिए और दूसरों के लिए कुछ सुखद करने की कोशिश की।
मेरी स्क्रिप्ट कोई उपयोगी काम नहीं करती है, लेकिन मुझे लगता है कि कम या ज्यादा शुरुआत लेखकों को कोसने के लिए यह कुछ सिखाएगा, और अगर कोई टिप्पणी है, तो मैं उन लोगों से सीखूंगा जो मेरी गलतियों को इंगित करते हैं।

पृष्ठभूमि

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

से शुरू करें

तो, हम अपने चर को परिभाषित करते हैं
#        FILE_NAME="run_Lola_run" #       WATCH_DIR="/home/mcleod/test" #           LOCK_FILE="${WATCH_DIR}/monitor_file.lock" #         PID_FILE="${WATCH_DIR}/monitor_file.pid" #          JOB_LOCK_FILE="${WATCH_DIR}/job_monitor_file.lock" #         LOG="${WATCH_DIR}/monitor_file_work.log" #          ERR_LOG="${WATCH_DIR}/monitor_file_error.log" #        RANGE=100 


अगला, माता-पिता की शुरुआत और रोक के सुविधाजनक नियंत्रण के लिए, हम एक छोटी सी स्थिति लिखते हैं
 case $1 in "start") start ;; "stop") stop ;; *) usage ;; esac exit 


रूपरेखा तैयार है, सभी चर भी परिभाषित किए गए हैं, अब हमें उपयोग किए गए कार्यों का वर्णन करने की आवश्यकता है


अब मैं कार्यों का वर्णन करूँगा क्योंकि वे अधिक जटिल हो जाते हैं। उनमें से सबसे सरल उपयोग समारोह है, यह इस तरह दिखता है
 #   usage() { echo "$0 (start|stop)" } 

जटिलता के लिए आगे _log फ़ंक्शन है
 #   _log() { process=$1 shift echo "${process}[$$]: $*" } 

अब डेमॉन स्टॉप फंक्शन
 #    stop() { #   pid ,       pid  if [ -e ${PID_FILE} ] then _pid=$(cat ${PID_FILE}) kill $_pid rt=$? if [ "$rt" == "0" ] then echo "Daemon stop" else echo "Error stop daemon" fi else echo "Daemon is't running" fi } 

यहां मैं लॉगिंग फ़ंक्शन का उपयोग नहीं करता हूं, जैसा कि यहाँ संदेश कंसोल पर प्रदर्शित होने चाहिए।
अब मैं शायद आपको सबसे जटिल आरंभ समारोह दे दूंगा। इसमें काम के सभी तर्क और स्क्रिप्ट के प्रदर्शन के क्षण शामिल हैं।
 #    start() { #     pid        if [ -e $PID_FILE ] then _pid=$(cat ${PID_FILE}) if [ -e /proc/${_pid} ] then echo "Daemon already running with pid = $_pid" exit 0 fi fi #    touch ${LOG} touch ${ERR_LOG} #   ,      cd / #   ,      exec > $LOG exec 2> $ERR_LOG exec < /dev/null #    ,  .      ( #             trap "{ rm -f ${PID_FILE}; exit 255; }" TERM INT EXIT #     while [ 1 ] do #      if ls -1 ${WATCH_DIR} | grep "^${FILE_NAME}$" 2>&1 >/dev/null then _log "parent" "File found" rm -f ${WATCH_DIR}/${FILE_NAME} _log "parent" "File deleted" #            number=$RANDOM let "number %= $RANGE" _log "parent" "Genereated number $number" JOBS[${#JOBS[@]}]=$number fi #     0,   ,       if [ "${#JOBS[@]}" -gt "0" ] then if [ ! -e ${JOB_LOCK_FILE} ] then run_job _log "parent" "Running job with pid $!" unset JOBS[0] JOBS=("${JOBS[@]}") _log "parent" "Jobs in queue [${#JOBS[@]}]" fi fi #    sleep 1 done exit 0 )& #  pid   ,    echo $! > ${PID_FILE} } 

खैर, वंशज लॉन्च समारोह ही
 #   .       JOBS,   run_job() { #    .          /, ..      ( #        trap "{ rm -f ${JOB_LOCK_FILE}; exit 255; }" TERM INT EXIT #         if [ ! -e ${JOB_LOCK_FILE} ] then #   pid   ,    echo "$$" > ${JOB_LOCK_FILE} _log "child" "Job with pid $$" #     seconds=${JOBS[0]} #  ,     ,      unset JOBS _log "child" "Sleep seconds $seconds" sleep ${seconds} else _log "child" "Lock file is exists" fi #  exit 0 )& } 

ठीक है, अब यदि आप उपरोक्त सभी को एक फ़ाइल में जोड़ते हैं और इसे निष्पादित करने का अधिकार देते हैं, तो मुझे लगता है कि यह आपके लिए मुश्किल नहीं होगा। वैसे, शुरू करने से पहले, मैं आपको सलाह देता हूं कि आप WATCH_DIR चर के मूल्य को उस निर्देशिका के पथ में बदल दें जिसमें स्क्रिप्ट run_Lola_run नामक फ़ाइल की तलाश करेगी।
यहाँ मेरा आउटपुट लॉग फ़ाइल है
 parent[32338]: File found parent[32338]: File deleted parent[32338]: Genereated number 96 parent[32338]: Running job with pid 32385 parent[32338]: Jobs in queue [0] child[32338]: Job with pid 32338 child[32338]: Sleep seconds 96 parent[32338]: File found parent[32338]: File deleted parent[32338]: Genereated number 46 parent[32338]: File found parent[32338]: File deleted parent[32338]: Genereated number 1 parent[32338]: Running job with pid 32694 parent[32338]: Jobs in queue [1] child[32338]: Job with pid 32338 child[32338]: Sleep seconds 46 parent[32338]: Running job with pid 371 parent[32338]: Jobs in queue [0] child[32338]: Job with pid 32338 child[32338]: Sleep seconds 1 

मुझे उम्मीद है कि यह पोस्ट किसी को मार के विकास में मदद करेगी।

पुनश्च: चौकस पाठक ने देखा होगा कि लॉग में हर जगह एक ही प्रक्रिया संख्या होती है। क्योंकि बैश में कोई शुद्ध कांटा नहीं है, यह यहां होता है, हम कह सकते हैं, आवश्यक कोड को () & में चलाकर अनुकरण, जो इसे एक अलग प्रक्रिया में लॉन्च करता है, लेकिन एक ही समय में चर को अपरिवर्तित रखता है। और हम जानते हैं कि बैश में वर्तमान प्रक्रिया संख्या $ $ चर में संग्रहीत की जाती है। इसलिए, लॉग फ़ाइल में समान प्रक्रिया संख्या प्रदर्शित होती है। इसीलिए start function $ echo $ के साथ समाप्त होता है! > $ {PID_FILE}।

Source: https://habr.com/ru/post/In151771/


All Articles