मैं शेल स्क्रिप्ट के लिए एक सेवा कैसे बना सकता हूं ताकि मैं इसे डेमॉन की तरह शुरू और रोक सकूं?


22

मैं सेंटोस 7 का उपयोग कर रहा हूं कि मेरा उद्देश्य हर पांच सेकंड के लिए क्रोन बनाना है लेकिन जैसा कि मैंने शोध किया कि हम केवल एक मिनट के लिए क्रोन का उपयोग कर सकते हैं इसलिए मैं अब क्या कर रहा हूं मैंने एक शेल फ़ाइल बनाई है।
hit.sh

while sleep 5; do curl http://localhost/test.php; done

लेकिन मैंने इसे राइट क्लिक करके मैन्युअल रूप से हिट किया है।

मैं जो चाहता हूं वह उस फ़ाइल के लिए एक सेवा बनाना है ताकि मैं इसे स्वचालित रूप से शुरू और बंद कर सकूं।

मुझे सेवा बनाने के लिए स्क्रिप्ट मिली

#!/bin/bash
# chkconfig: 2345 20 80
# description: Description comes here....

# Source function library.
. /etc/init.d/functions

start() {
    # code to start app comes here 
    # example: daemon program_name &
}

stop() {
    # code to stop app comes here 
    # example: killproc program_name
}

case "$1" in 
    start)
       start
       ;;
    stop)
       stop
       ;;
    restart)
       stop
       start
       ;;
    status)
       # code to check status of app comes here 
       # example: status program_name
       ;;
    *)
       echo "Usage: $0 {start|stop|status|restart}"
esac

exit 0 

लेकिन मुझे नहीं पता कि मैंने जो तरीके शुरू करने या रोकने के तरीके बताए, मैंने हिट.श की वही सामग्री रखने की कोशिश की, start(){}लेकिन इसने }स्टॉप मेथड के लिए त्रुटि दी ।


क्या /usr/bin/myscriptयह ठीक काम करता है जब आप इसे अपने दम पर चलाते हैं? echo $?जब स्क्रिप्ट ने एक रन पूरा कर लिया है तो उसका आउटपुट क्या है ? क्या यह 203 है?
अलेक्जेंडर

@Alexander /usr/bin/myscript.shटर्मिनल के माध्यम से क्रियान्वित करने पर ठीक काम करता है और echo$?मुझे दिया1
codegasmer

यदि कोई समस्या नहीं है, तो स्क्रिप्ट को त्रुटि कोड 0 वापस करना चाहिए। त्रुटि कोड 1 एक त्रुटि इंगित करता है।
अलेक्जेंडर

जवाबों:


30

यदि आप अपने कोड नमूने का पुन: उपयोग करना चाहते हैं, तो यह कुछ ऐसा दिख सकता है:

#!/bin/bash

case "$1" in 
start)
   /path/to/hit.sh &
   echo $!>/var/run/hit.pid
   ;;
stop)
   kill `cat /var/run/hit.pid`
   rm /var/run/hit.pid
   ;;
restart)
   $0 stop
   $0 start
   ;;
status)
   if [ -e /var/run/hit.pid ]; then
      echo hit.sh is running, pid=`cat /var/run/hit.pid`
   else
      echo hit.sh is NOT running
      exit 1
   fi
   ;;
*)
   echo "Usage: $0 {start|stop|status|restart}"
esac

exit 0 

स्वाभाविक रूप से, वह स्क्रिप्ट जिसे आप एक सेवा के रूप में निष्पादित करना चाहते हैं /usr/local/bin/hit.sh, उदाहरण के लिए जाना चाहिए , और उपरोक्त कोड को जाना चाहिए /etc/init.d/hitservice

प्रत्येक रनवेल के लिए जिसे इस सेवा को चलाने की आवश्यकता है, आपको एक संबंधित सिमलिंक बनाने की आवश्यकता होगी। उदाहरण के लिए, एक सिमलिंक नाम /etc/init.d/rc5.d/S99hitserviceसे रनलेवल 5 के लिए सेवा शुरू होगी। बेशक, आप अभी भी इसे मैन्युअल रूप से service hitservice start/ के माध्यम से शुरू और बंद कर सकते हैं।service hitservice stop


क्या फ़ाइल को एक प्रत्यय की आवश्यकता है जैसे: hitservice.service? इसके बाद: backupservice.service शुरू करने में विफल: इकाई नहीं मिली। CentOS 7 पर ऐसा क्यों है इसका उत्तर के रूप में सुझाया गया है
Spektakulatius

@ Code.IT ध्यान दें कि ओपी एक SystemV स्क्रिप्ट चाहता था, स्क्रिप्ट नहीं systemd, इस प्रकार किसी प्रत्यय की आवश्यकता नहीं है। आपको पुरानी स्क्रिप्ट को systemdबस ठीक से चलाने में सक्षम होना चाहिए । क्या आपने कोशिश की है systemctl enable hitservice?
दिमित्री ग्रिगोरीव

@DmitryGrigoryev: यह स्क्रिप्ट कई उदाहरणों को नहीं रोकती है और न ही बनाए गए सभी कई उदाहरणों को रोकती है , pidfile केवल अंतिम पिड की प्रक्रिया को संग्रहीत करता है।
लुसियानो

27

मेरा मानना ​​है कि CentOS 7 और इसके बाद के संस्करण systemd का उपयोग करते हैं। यदि आपके सिस्टम के लिए ऐसा है, तो निम्न प्रयास करें:

  1. वह स्क्रिप्ट कमांड रखें जिसे आप चलाना चाहते हैं /usr/bin/myscript

  2. स्क्रिप्ट को निष्पादन योग्य बनाना याद रखें chmod +x

  3. निम्न फ़ाइल बनाएँ:

/etc/systemd/system/my.service

[Unit]
Description=My Script

[Service]
Type=forking
ExecStart=/usr/bin/myscript

[Install]
WantedBy=multi-user.target
  1. सभी systemd सेवा फ़ाइलों को पुनः लोड करें: systemctl daemon-reload

  2. जांचें कि यह सेवा को शुरू करके काम कर रहा है systemctl start my

बोनस:

सिस्टमड सेवा के परीक्षण के लिए, दो विंडो पैन के साथ एक tmux वातावरण लॉन्च करना संभव है, जहां शीर्ष विंडो स्क्रिप्ट ( stdoutऔर stderr) से आउटपुट की निगरानी करती है और नीचे की खिड़की का उपयोग सेवाओं को फिर से शुरू करने के लिए किया जा सकता है। यह tmuxस्थापित करने की आवश्यकता है, तो बस:

tmux new-session \; select-layout even-horizontal \; split-window -v journalctl -o cat --since=@$(date +%s) -f -u my \; rotate-window \; set -g status-bg colour0 \; set -g status-fg colour9 \; attach

इसके बाद सेवा को फिर से शुरू करें:

systemctl restart my

के tmuxसाथ बाहर निकलें ctrl-dऔर फिर ctrl-c


जवाब देने के लिए धन्यवाद मैंने आपको हल करने की कोशिश की, लेकिन सेवा शुरू नहीं हो रही है क्या आप मेरे प्रश्न को देख सकते हैं मैंने विवरण जोड़ा
कोडग्रास

मुझे लगता है कि यह काम करेगा यदि आपकी स्क्रिप्ट विफल नहीं होती है, लेकिन त्रुटि कोड 0.
अलेक्जेंडर

4
अब मुझे सिस्टमड पसंद है!
डेनिसकोलडिन

1
स्क्रिप्ट को कहीं भी रखा जा सकता है, जब तक कि systemd सेवा इसे एक्सेस और निष्पादित कर सकती है।
अलेक्जेंडर

2
मैं सिफारिश नहीं करेंगे Type=forking। संभावना Type=simpleहै कि पूछने वाले की आवश्यकता होगी लेकिन सामान्य रूप से फोर्किंग की सिफारिश नहीं की जाती है: 0pointer.de/public/systemd-man/… । लोग अपनी पुरानी init स्क्रिप्ट ले रहे हैं और उन्हें लपेट रहे हैं systemdताकि उनकी सेवा का स्टार्टअप चला जाए systemd(init-script(service))। हालांकि systemdयह init स्क्रिप्ट के लिए एक प्रतिस्थापन है, इसलिए आपको सीधे सेवा को कॉल करना चाहिए systemdताकि यह ऐसा दिखे systemd(service)
सेंटिमेन

3

यह एक सेवा के रूप में मेरी स्क्रिप्ट है:

[Unit]
Description=To change In test buffer
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/test.sh
TimeoutStartSec=0

[Install]
WantedBy=default.target

2

Fpm पर एक नज़र डालें। यह एक उपकरण है जो आपके लिए init स्क्रिप्ट बनाएगा। कई प्लेटफार्मों (सिस्टमड, अपस्टार्ट, एक्ट ..) पर काम करता है

https://github.com/jordansissel/fpm


0

बैश सेवा प्रबंधक परियोजना देखें : https://github.com/reduardo7/bash-service-manager

कार्यान्वयन का उदाहरण

#!/usr/bin/env bash

export PID_FILE_PATH="/tmp/my-service.pid"
export LOG_FILE_PATH="/tmp/my-service.log"
export LOG_ERROR_FILE_PATH="/tmp/my-service.error.log"

. ./services.sh

run-script() {
  local action="$1" # Action

  while true; do
    echo "@@@ Running action '${action}'"
    echo foo
    echo bar >&2

    [ "$action" = "run" ] && return 0
    sleep 5
    [ "$action" = "debug" ] && exit 25
  done
}

before-start() {
  local action="$1" # Action

  echo "* Starting with $action"
}

after-finish() {
  local action="$1" # Action
  local serviceExitCode=$2 # Service exit code

  echo "* Finish with $action. Exit code: $serviceExitCode"
}

action="$1"
serviceName="Example Service"

serviceMenu "$action" "$serviceName" run-script "$workDir" before-start after-finish

उदाहरण का उपयोग करें

$ ./example-service
# Actions: [start|stop|restart|status|run|debug|tail(-[log|error])]

$ ./example-service start
# Starting Example Service service...

$ ./example-service status
# Serive Example Service is runnig with PID 5599

$ ./example-service stop
# Stopping Example Service...

$ ./example-service status
# Service Example Service is not running
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.