วิธี "เหมาะสม" เพื่อทดสอบว่าบริการกำลังทำงานอยู่ในสคริปต์หรือไม่


96

ปัญหาของฉัน:

ฉันกำลังเขียนสคริปต์ทุบตีและในนั้นฉันต้องการตรวจสอบว่าบริการที่กำหนดทำงานอยู่หรือไม่

$ service [service_name] statusฉันรู้วิธีการทำด้วยตัวเองด้วย

แต่ (โดยเฉพาะอย่างยิ่งตั้งแต่การย้ายไปยัง systemd) ที่พิมพ์ข้อความจำนวนมากที่ไม่ยุ่งยากในการแยกวิเคราะห์ ฉันสันนิษฐานว่ามีคำสั่งสำหรับสคริปต์ที่มีเอาต์พุตแบบง่ายหรือค่าส่งคืนที่ฉันสามารถตรวจสอบได้

แต่ 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" จะถือว่าใช้งานได้หากพวกเขาออกจากที่ประสบความสำเร็จแนวคิดที่ว่าพวกเขาให้บริการที่ไม่จำเป็นต้องใช้ภูต ( เช่นพวกเขากำหนดค่าบางแง่มุมของระบบ) หน่วยที่เกี่ยวข้องกับ daemons จะใช้งานได้ก็ต่อเมื่อ daemon ยังคงทำงานอยู่


ระวังเกี่ยวกับบริการภาพ พวกเขาเป็นเพียงinactiveหรือactivatingและทั้งสองsystemctl statusและsystemctl is-activeออกด้วย 3 (ณsystemd-241 ) วิธีแก้ปัญหา:systemctl show service | grep -qx ActiveStatus=activating
Alois Mahdal

@Alois ฉันสงสัยว่าคุณเจอสถานการณ์แบบไหนในที่ที่คุณต้องการให้มีการใช้งานเซอร์วิสช็อตช็อต คุณมีตัวอย่างหรือไม่
Stephen Kitt

แน่นอน @StephenKitt เครื่องมือfooทำบางสิ่งบางอย่างกับระบบที่เกี่ยวข้องกับการรีบูตและใช้บริการ one-shot กล่าวfoo_cleanupในการบู๊ตครั้งถัดไปเพื่อล้างสิ่งต่างๆ ฉันกำลังทดสอบนี้ (สคริปต์ของฉันถูกกำหนดเวลาไว้เป็นบริการด้วย) และต้องการรวบรวมข้อผิดพลาดหลังจากนั้น แต่เมื่อใด (ต่อมาเพลง vsauce) หนึ่งในเกณฑ์ก็คือว่าfoo_cleanupเสร็จแล้ว ("หยุดการใช้งานอยู่")
Alois Mahdal

มันอาจคุ้มค่าที่ชี้ให้เห็นว่า 'is-failed' เป็นตัวเลือกเช่นกันและมีประโยชน์หากคุณต้องการดำเนินการตามบริการที่ไม่ได้เริ่ม
Phill Healey

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 สำหรับคำตอบที่ซับซ้อน กรุณาระบุ distros ที่จะยอมรับ--versionตัวเลือกด้วย systemctl
SK Venkat

11

ในฐานะที่เป็นส่วนเติมเต็มให้คำตอบ Zanna ของที่--valueตัวเลือกสำหรับการsystemctl showได้รับการแนะนำให้รู้จักกับรุ่น 230 ของ systemd ดังนั้นมันอาจไม่สามารถใช้ได้ใน distros บางอย่างเช่น debian jessie

ในกรณีนี้เราสามารถเลียนแบบตัวเลือกโดยใช้ sed:

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

1
+1 สำหรับชี้ให้เห็นถึงรุ่นแนะนำมูลค่า & distro ซึ่งจะไม่ทำงาน
SK Venkat

3

ฉันพบว่ามีประโยชน์สำหรับการดำเนินการบรรทัดคำสั่งหรือถ้าคุณกำลังสร้างสคริปต์

คัดลอกมาจาก @StephenKitt

การดำเนินการนี้จะตรวจสอบว่าบริการไม่ทำงานและเริ่มบริการใหม่หรือไม่

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

||มีตรวจสอบว่าค่าตอบแทนจาก systemctl เป็นที่ไม่ใช่ศูนย์ความหมายถ้ามันไม่ได้ใช้งานตามที่อธิบายไว้โดยผู้เขียน


คุณสามารถใช้ `is-failed 'เพื่อทดสอบว่าจำเป็นต้องรีสตาร์ทหรือไม่ ดูเหมือนง่ายขึ้นเล็กน้อยสำหรับการรีสตาร์ทบริการที่ล้มเหลว
Phill Healey

ใช่ แต่สำหรับฉัน .. ฉันต้องการฝึกฝนตัวเองและคิดว่าทุกอย่างทำงานได้เมื่อมันไม่ใช่ ดังนั้นฉันสามารถไปตรวจสอบสิ่งของอื่น ๆ ด้วยได้ เพียงแค่คุณต้องการตรวจสอบว่ามันไม่ทำงานหรือไม่ 'is-failed' เป็นตัวเลือกที่ถูกต้อง :)
เครื่องหมายดอกจัน

3


ผมสายเกินไปที่จะเลี้ยง แต่ใช้ systemctl คือใช้งานพร้อมด้วย&&และ||นี้ในสคริปต์เคยชินเป็นกรณีที่ตลอดเวลา ด้านล่างเป็นหนึ่งที่ฉันใช้สำหรับ Tomcat แต่สามารถใช้ในวิธีการโต้แย้งและผ่านชื่อบริการเป็นข้อโต้แย้งถ้าคุณต้องตรวจสอบบริการที่หลากหลาย แต่มันอยู่นอกขอบเขตที่นี่

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ไหน? นอกจากนี้ยัง[[ไม่ได้เปลือกมาตรฐาน
Toby Speight

@TobySpeight คุณต้องอ่านโพสต์ของฉันอีกเล็กน้อยตามที่ฉันได้กล่าวถึงในโพสต์ของฉัน "นี่คือวิธีที่ฉันใช้ประโยชน์ .... เพียงแบ่งปันของฉัน" ฉันไม่เคยบอกว่ามันเป็นการใช้งานเชลล์มาตรฐานถ้าคุณทำให้มันเป็นวงเล็บเดี่ยวมันจะกลายเป็นแล้ว แต่มันอยู่นอกขอบเขตที่นี่ นอกจากนี้ผมพูดถึงการใช้งานด้านล่างบรรทัดเดียวง่ายที่จะทำโดยใช้และ&& ||
SAGAR แนร์

2

แทนที่จะใช้คำสั่ง sed เช่นเดียวกับคำตอบของ Oxmel มันก็เพียงพอที่จะใช้cut -d'=' -f 2สำหรับคุณสมบัติทุกประเภทที่สอบถาม:

ตัวอย่างเช่น:

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

เยี่ยมมาก แต่คุณต้องให้คำอธิบายเกี่ยวกับสิ่งที่คำสั่งเหล่านั้นทำ
Phill Healey

-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

แหล่ง


บริการบางอย่างอาจไม่มีชื่อเดียวกันและผู้ใช้รายใดก็ตามสามารถเรียกใช้คำสั่งที่จับคู่โดยไม่ได้ตั้งใจ - นี่เป็นสูตรสำหรับภัยพิบัติ
Toby Speight
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.