ความแตกต่างระหว่าง systemctl และคำสั่งบริการ


143

systemdทำให้เรามีsystemctlชุดคำสั่งซึ่งส่วนใหญ่จะใช้ในการเปิดใช้งานบริการเพื่อเริ่มเวลาบูต systemctlนอกจากนี้เรายังสามารถเริ่มหยุดโหลดรีสตาร์ทและตรวจสอบสถานะของการให้บริการด้วยความช่วยเหลือของ

ตัวอย่างเช่นเราสามารถทำsudo systemctl enable service_nameและservice_nameจะเริ่มโดยอัตโนมัติในเวลาบูต นอกจากนี้เรายังสามารถปิดการใช้งานบริการไม่ให้เริ่มในเวลาบูต

ข้อแตกต่างระหว่างคำสั่งserviceและกับsystemctlคำสั่งที่systemctlสามารถใช้เพื่อเปิดใช้งานจุดเริ่มต้นของบริการ ณ รันไทม์หรือไม่? เราสามารถใช้systemctlบริการใด ๆ ได้บ้าง? มีความแตกต่างที่สำคัญอะไรอีกบ้าง?


ฉันคิดว่าคุณเลือกคำตอบที่ผิดตัวเอง
Evan Carroll

คำตอบ:


144

serviceคำสั่งเป็นสคริปต์เสื้อคลุมที่ช่วยให้ผู้ดูแลระบบเพื่อเริ่มหยุดและตรวจสอบสถานะของการให้บริการโดยไม่ต้องกังวลมากเกินไปเกี่ยวกับระบบ init ที่เกิดขึ้นจริงถูกนำมาใช้ ก่อนที่จะมีการแนะนำของ systemd มันเป็นเสื้อคลุมสำหรับ/etc/init.dสคริปต์และinitctlคำสั่งของพุ่งพรวดและตอนนี้มันเป็นเสื้อคลุมสำหรับทั้งสองนี้และ systemctlเช่นกัน

ใช้แหล่งที่มาลุค!

จะตรวจสอบการพุ่งพรวด:

# Operate against system upstart, not session
unset UPSTART_SESSION
if [ -r "/etc/init/${SERVICE}.conf" ] && which initctl >/dev/null \
   && initctl version 2>/dev/null | grep -q upstart \
   && initctl status ${SERVICE} 2>/dev/null 1>/dev/null
then
   # Upstart configuration exists for this job and we're running on upstart

หากไม่ได้ผลก็จะมองหา systemd:

if [ -d /run/systemd/system ]; then
   is_systemd=1
fi

...

# When this machine is running systemd, standard service calls are turned into
# systemctl calls.
if [ -n "$is_systemd" ]
then

และถ้ามันล้มเหลวเช่นกันมันจะกลับไปที่/etc/init.dสคริปต์System V :

run_via_sysvinit() {
   # Otherwise, use the traditional sysvinit
   if [ -x "${SERVICEDIR}/${SERVICE}" ]; then
      exec env -i LANG="$LANG" LANGUAGE="$LANGUAGE" LC_CTYPE="$LC_CTYPE" LC_NUMERIC="$LC_NUMERIC" LC_TIME="$LC_TIME" LC_COLLATE="$LC_COLLATE" LC_MONETARY="$LC_MONETARY" LC_MESSAGES="$LC_MESSAGES" LC_PAPER="$LC_PAPER" LC_NAME="$LC_NAME" LC_ADDRESS="$LC_ADDRESS" LC_TELEPHONE="$LC_TELEPHONE" LC_MEASUREMENT="$LC_MEASUREMENT" LC_IDENTIFICATION="$LC_IDENTIFICATION" LC_ALL="$LC_ALL" PATH="$PATH" TERM="$TERM" "$SERVICEDIR/$SERVICE" ${ACTION} ${OPTIONS}
   else
      echo "${SERVICE}: unrecognized service" >&2
      exit 1
   fi
}

...
run_via_sysvinit

เนื่องจากserviceคำสั่งเป็น wrapper ที่ค่อนข้างง่ายจึงสนับสนุนชุดย่อยของการดำเนินการที่ จำกัด เมื่อเทียบกับสิ่งที่ระบบ init จริงอาจมีให้

เพื่อความสะดวกในการพกพาเหนือ Ubuntu รุ่นต่าง ๆ ผู้ใช้สามารถใช้serviceคำสั่งเพื่อเริ่มหยุดรีสตาร์ทหรือตรวจสอบสถานะของบริการได้อย่างน่าเชื่อถือ สำหรับงานที่ซับซ้อนมากขึ้นอย่างไรก็ตามคำสั่งจริงที่ใช้อยู่อาจเป็นinitctlหรือsystemctlหรือ/etc/init.dอาจต้องใช้สคริปต์โดยตรง

นอกจากนี้การใช้ wrapper serviceสคริปต์ในบางกรณีอาจทำมากกว่าคำสั่งที่เทียบเท่าโดยตรง ตัวอย่างเช่น:

  • มันรัน/etc/init.dสคริปต์ในสภาพแวดล้อมที่สะอาดเสมอ (หมายเหตุการเรียกใช้ envคำสั่งแบบยาวในrun_via_sysvinitฟังก์ชันด้านบน)
  • มันแมปrestartบนระบบพุ่งพรวดเพื่อการรวมกันของstop/ startเนื่องจากธรรมดาinitctl restartจะผิดพลาดออกหากบริการไม่ได้ทำงานอยู่แล้ว
  • มันหยุดซ็อกเก็ตเมื่อหยุดบริการ systemd ซึ่งมีซ็อกเก็ตที่เกี่ยวข้อง:

    case "${ACTION}" in
      restart|status)
         exec systemctl $sctl_args ${ACTION} ${UNIT}
      ;;
      start|stop)
         # Follow the principle of least surprise for SysV people:
         # When running "service foo stop" and foo happens to be a service that
         # has one or more .socket files, we also stop the .socket units.
         # Users who need more control will use systemctl directly.
    

บริการพุ่งพรวดถูกเปิดใช้งานโดยตรงในไฟล์การกำหนดค่าบริการ (หรือปิดใช้งานผ่านการแทนที่) และสคริปต์ System V ถูกเปิดใช้งานหรือปิดการใช้งานด้วยupdate-rc.dคำสั่ง (ซึ่ง symlink ที่มีการจัดการใน/etc/rc*ไดเรกทอรี) ดังนั้นserviceคำสั่งจึงไม่เกี่ยวข้องกับการเปิดใช้งาน .


34
  • systemd เข้ากันได้กับ SysV
  • โหลดบริการแบบขนานเมื่อเริ่มต้น
  • มันให้การเปิดใช้งานตามความต้องการของบริการ
  • มันขึ้นอยู่กับการพึ่งพา
  • และอีกมากมายฉันเดาว่า ...

มีมากกว่าสิ่งที่คุณพูดถึงที่systemctlมีความสามารถ

systemd ทำงานร่วมกับหน่วยมีหน่วยประเภทต่าง ๆ : เป้าหมายบริการซ็อกเก็ต ฯลฯ เป้าหมายเป็นแนวคิดเดียวกับ runlevels พวกมันเป็นหน่วยรวมเข้าด้วยกัน

คุณสามารถใช้systemctlเพื่อตั้งค่าหรือรับค่าเริ่มต้นเป้าหมายของระบบ

systemctl get-default

คุณสามารถไปสู่เป้าหมายอื่นได้:

systemctl isolate multiuser.target

เป้าหมายอื่น ๆ คือ: ผู้ใช้หลายคน, กราฟิก, recue, ฉุกเฉิน, รีบูต, poweroff

อย่างที่คุณพูดคุณสามารถใช้systemctlเพื่อจัดการบริการบางคำสั่งอื่น ๆ ที่เกี่ยวข้องกับการจัดการบริการที่ฉันรู้คือ:

# Restarts a service only if it is running.
systemctl try-restart name.service

# Reloads configuration if it's possible.
systemctl reload name.service

# try to reload but if it's not possible restarts the service
systemctl reload-or-restart name.service

คุณสามารถใช้มันเพื่อค้นหาข้อมูลเกี่ยวกับสถานะบริการ:

systemctl status name.service

systemctl is-active name.service # running
systemctl is-enabled name.service # will be activated when booting
systemctl is-failed name.service # failed to load

คุณสามารถปิดบังหรือเปิดโปงบริการ:

systemctl mask name.service
systemctl unmask name.service

เมื่อคุณปิดบังบริการที่จะเชื่อมโยง/dev/nullดังนั้นบริการอื่น ๆ ด้วยตนเองหรือโดยอัตโนมัติไม่สามารถเปิดใช้งาน / เปิดใช้งานได้ (คุณควรเปิดโปงก่อน)

การใช้ systemctl อื่นคือการแสดงรายการหน่วย:

systemctl list-units

รายการใดที่ทุกหน่วยโหลดและใช้งานอยู่

รายชื่อหน่วยบริการ:

systemctl list-units --type=service

หรือเพื่อแสดงรายการหน่วยทั้งหมดที่มีอยู่ไม่เพียงแค่โหลดและเปิดใช้งาน:

systemctl list-unit-files

คุณสามารถสร้างนามแฝงหรือควบคุมเครื่องระยะไกล

systemctl --host ravexina@192.168.56.4 list-units

ในทางกลับกันserviceทำสิ่งที่ต้องทำจัดการบริการและไม่มีอะไรเกี่ยวข้องกับธุรกิจของคนอื่น)


1
นั่นเป็นคำตอบที่สมบูรณ์แบบมีอะไรที่serviceสามารถทำได้ แต่ไม่ใช่systemctl?
luv.preet

ไม่มีอะไรที่ฉันรู้ว่าฉันคิดว่าการมีหน้าพนักงานบริการดูจะมีประโยชน์
Ravexina

1
มีความแตกต่างชัดเจนสองสาม ไวยากรณ์คือหนึ่ง อีกอย่างคือสคริปต์ของ systemv ไม่เคยจัดการกับซ็อกเก็ตเท่าที่ฉันรู้ ความจริงที่ว่า systemd กำลังพยายามจัดการกับประเภทของเครือข่ายเป็นอีกสิ่งหนึ่งและเป็นจุดวิจารณ์บ่อยๆ เหนือสิ่งอื่นใด systemd กำลังพยายามทำมากกว่าเริ่มบริการ
Sergiy Kolodyazhnyy

ฉันต้องการร้องเรียนที่นี่เกี่ยวกับ systemd การซ่อนข้อความบันทึกจากservice startความพยายามที่ล้มเหลว Pre-systemd service startให้ฉันดูทันทีว่าทำไมบริการของฉันไม่เริ่ม โพสต์ systemd ฉันต้องดูสี่หรือห้าล็อกที่แตกต่างกันก่อนที่จะหามัน ทั้งหมดที่กล่าวว่าความคิดเห็นของฉันไม่ต้องสงสัยเลยว่าจะปิดหัวข้อและอาจถูกลบ
Ross Presser

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