यदि स्क्रिप्ट में कोई सेवा चल रही है तो परीक्षण करने का "उचित" तरीका


96

मेरी समस्या:

मैं एक बैश स्क्रिप्ट लिख रहा हूं और इसमें मैं यह जांचना चाहूंगा कि क्या कोई दी गई सेवा चल रही है।

मुझे पता है कि यह मैन्युअल रूप से कैसे करना है, के साथ $ service [service_name] status

लेकिन (विशेष रूप से सिस्टमड के कदम के बाद से) जो पाठ के एक पूरे गुच्छा को प्रिंट करता है जो पार्स करने के लिए थोड़ा गड़बड़ है। मैंने मान लिया कि साधारण आउटपुट वाली स्क्रिप्ट के लिए एक कमांड बनाई गई है या एक रिटर्न वैल्यू जिसकी मैं जांच कर सकता हूं।

लेकिन केवल Googling के चारों ओर "ओह, बस ps aux | grep -v grep | grep [service_name]" परिणाम का एक टन उपज होता है। यह सबसे अच्छा अभ्यास नहीं हो सकता है, क्या यह है? क्या होगा अगर उस कमांड का एक और उदाहरण चल रहा है, लेकिन SysV init स्क्रिप्ट द्वारा शुरू नहीं किया गया है?

या मैं बस चुप हो जाऊं और अपने हाथों को थोड़े-से pgrep से गंदा कर दूं?

जवाबों:


139

systemctlइसके लिए एक is-activeउपकमांड है:

systemctl is-active --quiet service

serviceसक्रिय होने पर स्थिति शून्य से बाहर निकलेगा, अन्यथा शून्य, अन्यथा, यह स्क्रिप्ट के लिए आदर्श बनाता है:

systemctl is-active --quiet service && echo Service is running

यदि आप --quietइसे छोड़ देते हैं तो यह वर्तमान स्थिति को उसके मानक आउटपुट में भी आउटपुट करेगा।

जैसा कि don_crissti द्वारा बताया गया है , कुछ इकाइयाँ सक्रिय हो सकती हैं, भले ही सेवा प्रदान करने के लिए कुछ भी नहीं चल रहा हो: "RemainAfterExit" के रूप में चिह्नित इकाइयाँ सक्रिय मानी जाती हैं यदि वे सफलतापूर्वक बाहर निकल जाती हैं, तो यह विचार किया जा रहा है कि उन्हें ऐसी सेवा प्रदान करनी होगी जिसके लिए किसी डेमन की जरूरत नहीं है ( जैसे वे सिस्टम के कुछ पहलू को कॉन्फ़िगर करते हैं)। डेमन से जुड़ी इकाइयां हालांकि तभी सक्रिय होंगी जब डेमन अभी भी चल रहा है।


Oneshot सेवाओं के बारे में सावधान। वे ही कर रहे हैं inactiveया activatingऔर दोनों systemctl statusऔर systemctl is-active(के रूप में बाहर निकलने 3. साथ systemd-241 वर्कअराउंड):systemctl show service | grep -qx ActiveStatus=activating
Alois Mahdal

@ मैं सोच रहा हूँ कि आप किस तरह के परिदृश्यों का सामना कर चुके हैं जहाँ आप एक ऑनशॉट सेवा को सक्रिय होने पर विचार करना चाहते हैं; आपके पास कोई उदाहरण है?
स्टीफन किट

ज़रूर, @StephenKitt। टूल fooरिबूट से जुड़े सिस्टम के लिए कुछ करता है और foo_cleanupचीजों को साफ करने के लिए अगले बूट पर एक-शॉट सेवा का उपयोग करता है । मैं इस (मेरी स्क्रिप्ट भी एक सेवा के रूप शेड्यूल किया गया है) और बाद में त्रुटियों एकत्र करना चाहते हैं परीक्षण कर रहा हूँ, लेकिन जब है बाद में (Vsauce संगीत)? वैसे एक मापदंड यह है कि foo_cleanupसमाप्त हो गया है ("सक्रिय होना बंद हो गया")।
Alois Mahdal

यह इंगित करने योग्य हो सकता है कि 'is-fail' भी एक विकल्प है, और उपयोगी है यदि आपको सेवा शुरू नहीं करने के आधार पर कार्रवाई करने की आवश्यकता है।
फिल हीली

33

systemctlस्क्रिप्टिंग के लिए उपयुक्त एक मोड है; के showबजाय का उपयोग करें status, और -p/ --propertiesऔर --valueविकल्प जोड़ने के लिए केवल उत्पादन आप चाहते हैं।

यहाँ एक उदाहरण है (एक Ubuntu 17.04 प्रणाली से):

$ systemctl show -p SubState --value NetworkManager
running

दौड़ना (या अन्यथा) एक है SubState। यदि आप जानना चाहते हैं कि क्या कोई सेवा सक्रिय है, तो संपत्ति का उपयोग करेंActiveState

$ systemctl show -p ActiveState --value x11-common
inactive
$ systemctl show -p SubState --value x11-common
dead

से नोट man:

show [PATTERN...|JOB...]
           Show properties of one or more units, jobs, or the manager
           itself. If no argument is specified, properties of the
           manager will be shown. If a unit name is specified, properties
           of the unit are shown, and if a job ID is specified,
           properties of the job are shown. By default, empty properties
           are suppressed. Use --all to show those too. To select specific
           properties to show, use --property=. This command is intended
           to be used whenever computer-parsable output is required. Use
           status if you are looking for formatted human-readable output.

-p, --property=
           When showing unit/job/manager properties with the show command,
           limit display to properties specified in the argument. The
           argument should be a comma-separated list of property names,
           such as "MainPID". Unless specified, all known properties are
           shown. If specified more than once, all properties with the
           specified names are shown. Shell completion is implemented for
           property names.

--value
           When printing properties with show, only print the value, and
           skip the property name and "=".

2
परिष्कृत उत्तर के लिए +1। कृपया ऐसे डिस्ट्रोस को निर्दिष्ट करें जो --versionsystemctl के साथ विकल्प स्वीकार करेगा ।
एसके वेंकट

11

ज़न्ना के जवाब के पूरक के रूप में, सिस्टम 230 के संस्करण के साथ --valueविकल्प systemctl showपेश किया गया है । तो यह कुछ डिस्ट्रोब्स पर उपलब्ध नहीं हो सकता है जैसे कि डेबियन जेसी।

इस मामले में, कोई sed का उपयोग करके विकल्प का अनुकरण कर सकता है:

$ systemctl show -p ActiveState sshd | sed 's/ActiveState=//g'
active
$ systemctl show -p SubState sshd | sed 's/SubState=//g'  
running

1
+1 इंगित करने के लिए - अंतराल परिचय संस्करण और डिस्ट्रो जो काम नहीं करेगा।
एसके वेंकट

3

मुझे यह कमांड लाइन के निष्पादन के लिए उपयोगी लगता है या यदि आप स्क्रिप्ट बना रहे हैं।

@StephenKitt से कॉपी किया गया

यह जाँच करेगा कि क्या सेवा डाउन है और सेवा पुनरारंभ करें

systemctl is-active --quiet <service name> || <service name> restart

||वहाँ की जाँच करता है, तो systemctl से वापसी मान गैर शून्य अर्थ अगर यह सक्रिय रूप में लेखक से समझाया नहीं है।


यदि पुनरारंभ की आवश्यकता है, तो आप परीक्षण के लिए `is-fail´ का भी उपयोग कर सकते हैं। यह एक विफल सेवा को पुनरारंभ करने के लिए थोड़ा अधिक सहज लगता है।
फिल हीली

हाँ, लेकिन मेरे लिए .. मैं अपने आप को अभ्यास करना चाहता था और यह मानता हूं कि जब यह नहीं है तो सब कुछ चल रहा है। इसलिए मैं चीजों को इसके साथ अन्य सामानों को सत्यापित करने के लिए जा सकता हूं। यदि आप केवल यह जांचना चाहते हैं कि क्या यह नहीं चल रहा है, तो 'is-fail' एक सही विकल्प है। :)
तारांकन चिह्न

3


मुझे पार्टी में बहुत देर हो चुकी है, हालाँकि सिस्टेमक्टल का उपयोग करना साथ-साथ सक्रिय है &&और ||स्क्रिप्ट में यह हर समय नहीं होगा। नीचे एक है जिसे मैंने टॉमकैट के लिए उपयोग किया है, लेकिन इसका उपयोग तर्कों को लेने की विधि में कर सकता है और सेवा नाम को तर्कों के रूप में पास कर सकता है यदि यू को कई सेवाओं की जांच करनी है, लेकिन इसके दायरे से बाहर है।

STATUS=`systemctl is-active tomcat.service`
  if [[ ${STATUS} == 'active' ]]; then
    echo "Execute your tasks ....."
  else 
    echo " Service not running.... so exiting "  
    exit 1  
  fi

यह है कि मैं कैसे का उपयोग किया .... बस मेरा साझा।

और सादगी और आसान सामान के लिए, यहां बताए गए दूसरों का अनुसरण करें:

systemctl -q is-active tomcat.service  && echo "Tomcat Runnung" || echo "Service is not running at all "

यह बस से बेहतर कैसे है if systemctl is-active --quiet tomcat.service? इसके अलावा, [[मानक शेल नहीं है।
टोबी स्पाइट

@TobySpeight आपको मेरी पोस्ट को थोड़ा और पढ़ने की ज़रूरत है जैसा कि मैंने अपनी पोस्ट में उल्लेख किया है "यह है कि मैंने कैसे उपयोग किया .... बस शेयरिंग मेरा।" मैंने कभी नहीं कहा, इसका एक मानक शेल उपयोग है, अगर आप इसे एकल ब्रैकेट बनाते हैं, तो यह बन जाएगा, लेकिन यहाँ गुंजाइश से बाहर है। इसके अलावा मैं नीचे का उपयोग करने के लिए आसान सिंगल लाइन उपयोग का उल्लेख करता हूं &&और ||
SAGAR नायर

2

ऑक्समेल के उत्तर में सेड कमांड का उपयोग करने के बजाय, यह cut -d'=' -f 2सभी प्रकार के गुणों के लिए उपयोग करने के लिए पर्याप्त है :

उदाहरण के लिए:

$ systemctl show -p ActiveState sshd | cut -d'=' -f2
active
$ systemctl show -p SubState sshd | cut -d'=' -f2
running

यह बहुत अच्छा है लेकिन आपको वास्तव में कुछ स्पष्टीकरण देने की आवश्यकता है कि वे क्या करते हैं।
फिल हीली

-1

बस इस महान छोटी स्क्रिप्ट मिल गया है:

#!/bin/bash
service=replace_me_with_a_valid_service

if (( $(ps -ef | grep -v grep | grep $service | wc -l) > 0 ))
then
  echo "$service is running!!!"
else
  /etc/init.d/$service start
fi

स्रोत


सभी सेवाओं में एक ही नाम का निष्पादन योग्य नहीं है, और कोई भी उपयोगकर्ता एक कमांड चला सकता है जो गलती से मेल खाता है - यह आपदा के लिए एक नुस्खा है।
टोबे स्पाइट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.