ฉันจะแทนที่หรือกำหนดค่าบริการ systemd ได้อย่างไร


109

สคริปต์เริ่มต้น sysv จำนวนมากใช้ไฟล์ที่เกี่ยวข้องใน/etc/defaultการอนุญาตให้ผู้ดูแลระบบกำหนดค่า งานพุ่งพรวดสามารถแก้ไขได้โดยใช้.overrideไฟล์ ฉันจะแทนที่หรือกำหนดค่า systemd units ได้อย่างไรตอนนี้ systemd นั้นเป็นค่าเริ่มต้นใน Ubuntu


โปรดทราบว่าเมื่อล้างExecStart=ด้วยรายการว่างคุณไม่สามารถใส่ความคิดเห็นหลังจากที่มันชอบ: ExecStart= # Empty line to clear previous entries.นี้จะถูกนำมาเป็นExecStart=รายการอื่นและเพิ่มลงในรายการ PS ฉันไม่สามารถเพิ่มความคิดเห็นในคำตอบของ muru เนื่องจากชื่อเสียงที่ต่ำของฉัน
tysik

คำตอบ:


185

systemd/etc/defaultหน่วยไม่จำเป็นต้องเชื่อฟังไฟล์ใน systemdสามารถกำหนดค่าได้อย่างง่ายดาย แต่ต้องการให้คุณรู้ว่าไวยากรณ์ของไฟล์ systemd unit

แพคเกจจัดส่งไฟล์หน่วยโดยทั่วไป/lib/systemd/system/มา สิ่งเหล่านี้ไม่สามารถแก้ไขได้ แต่ช่วยให้คุณสามารถแทนที่ไฟล์เหล่านี้โดยการสร้างไฟล์ที่เหมาะสมในsystemd/etc/systemd/system/

สำหรับการให้บริการที่ได้รับแพคเกจจะให้foo /lib/systemd/system/foo.serviceคุณสามารถตรวจสอบสถานะของการใช้หรือดูบันทึกของการใช้systemctl status foo journalctl -u fooหากต้องการลบล้างบางสิ่งในคำจำกัดความของfooให้ทำ:

sudo systemctl edit foo

สิ่งนี้จะสร้างไดเรกทอรีที่/etc/systemd/systemตั้งชื่อตามหน่วยและoverride.confไฟล์ในไดเรกทอรีนั้น ( /etc/systemd/system/foo.service.d/override.conf) คุณสามารถเพิ่มหรือลบล้างการตั้งค่าโดยใช้ไฟล์นี้ (หรือ.confไฟล์อื่น ๆใน/etc/systemd/system/foo.service.d/)

การเอาชนะข้อโต้แย้งคำสั่ง

ใช้gettyบริการเช่น ว่าฉันต้องการให้ TTY2 autologin แก่ผู้ใช้ของฉัน (ไม่แนะนำให้เลือก แต่เป็นเพียงตัวอย่าง) TTY2 ดำเนินการโดยgetty@tty2บริการ ( tty2เป็นอินสแตนซ์ของแม่แบบ/lib/systemd/system/getty@service) หากต้องการทำสิ่งนี้ฉันต้องแก้ไขgetty@tty2บริการ

$ systemctl cat getty@tty2
# /lib/systemd/system/getty@.service
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

[Unit]
Description=Getty on %I
Documentation=man:agetty(8) man:systemd-getty-generator(8)
Documentation=http://0pointer.de/blog/projects/serial-console.html
After=systemd-user-sessions.service plymouth-quit-wait.service
After=rc-local.service

# If additional gettys are spawned during boot then we should make
# sure that this is synchronized before getty.target, even though
# getty.target didn't actually pull it in.
Before=getty.target
IgnoreOnIsolate=yes

# On systems without virtual consoles, don't start any getty. Note
# that serial gettys are covered by serial-getty@.service, not this
# unit.
ConditionPathExists=/dev/tty0

[Service]
# the VT is cleared by TTYVTDisallocate
ExecStart=-/sbin/agetty --noclear %I $TERM
Type=idle
Restart=always
RestartSec=0
UtmpIdentifier=%I
TTYPath=/dev/%I
TTYReset=yes
TTYVHangup=yes
TTYVTDisallocate=yes
KillMode=process
IgnoreSIGPIPE=no
SendSIGHUP=yes

# Unset locale for the console getty since the console has problems
# displaying some internationalized messages.
Environment=LANG= LANGUAGE= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETARY= LC_MESSAGES= LC_PAPER= LC_NAME= LC_ADDRESS= LC_TELEPHONE= LC_MEASUREMENT= LC_IDENTIFICATION=

[Install]
WantedBy=getty.target
DefaultInstance=tty1

โดยเฉพาะอย่างยิ่งฉันต้องเปลี่ยนExecStartสายซึ่งปัจจุบันคือ:

$ systemctl cat getty@tty2 | grep Exec     
ExecStart=-/sbin/agetty --noclear %I $TERM

หากต้องการลบล้างสิ่งนี้ให้ทำ:

sudo systemctl edit getty@tty2

และเพิ่ม:

[Service]
ExecStart=
ExecStart=-/sbin/agetty -a muru --noclear %I $TERM

โปรดทราบว่า:

  1. ฉันได้อย่างชัดเจนที่ชัดเจนExecStartก่อนที่จะตั้งมันอีกครั้งในขณะที่มันคือการตั้งค่าสารเติมแต่งคล้ายกับAfter, Environment(เป็นทั้งไม่ต่อตัวแปร) และEnvironmentFileและเมื่อเทียบกับการตั้งค่าเช่นเอาชนะหรือRestartSec สามารถมีได้หลายรายการสำหรับบริการเท่านั้นTypeExecStartType=oneshot
  2. ฉันต้องใช้ส่วนหัวที่เหมาะสม ในไฟล์ต้นฉบับExecStartอยู่ใน[Service]ส่วนดังนั้นการแทนที่ของฉันต้องใส่ExecStartใน[Service]ส่วนด้วย บ่อยครั้งที่ดูไฟล์บริการจริงที่ใช้อยู่systemctl catจะบอกคุณว่าคุณต้องแทนที่อะไรและอยู่ในส่วนใด

โดยปกติหากคุณแก้ไขไฟล์ systemd unit เพื่อให้มีผลบังคับใช้คุณต้องเรียกใช้:

sudo systemctl daemon-reload

อย่างไรก็ตามsystemctl editจะทำสิ่งนี้ให้คุณโดยอัตโนมัติ

ขณะนี้:

$ systemctl cat getty@tty2 | grep Exec
ExecStart=-/sbin/agetty --noclear %I $TERM
ExecStart=
ExecStart=-/sbin/agetty -a muru --noclear %I $TERM

$ systemctl show getty@tty2 | grep ExecS
ExecStart={ path=/sbin/agetty ; argv[]=/sbin/agetty -a muru --noclear %I $TERM ; ... }

และถ้าฉันทำ:

sudo systemctl restart getty@tty2

และกดCtrlAltF2presto! ฉันจะเข้าสู่บัญชีของฉันใน TTY นั้น

อย่างที่ฉันพูดไว้ก่อนหน้าgetty@tty2นี้เป็นตัวอย่างของแม่แบบ ดังนั้นถ้าฉันต้องการแทนที่อินสแตนซ์ทั้งหมดของเทมเพลตนั้น ที่สามารถทำได้โดยการแก้ไขแม่แบบเอง (ลบตัวระบุอินสแตนซ์ - ในกรณีนี้tty2):

systemctl edit getty@

การเอาชนะสิ่งแวดล้อม

กรณีการใช้งานทั่วไปของ/etc/defaultไฟล์คือการตั้งค่าตัวแปรสภาพแวดล้อม โดยปกติแล้ว/etc/defaultเป็นสคริปต์ของเชลล์ดังนั้นคุณสามารถใช้ภาษาของโครงสร้างได้ ด้วยsystemdอย่างไรก็ตามนี่ไม่ใช่กรณี คุณสามารถระบุตัวแปรสภาพแวดล้อมได้สองวิธี:

ผ่านไฟล์

สมมติว่าคุณได้ตั้งค่าตัวแปรสภาพแวดล้อมในไฟล์:

$ cat /path/to/some/file
FOO=bar

จากนั้นคุณสามารถเพิ่มลงในการแทนที่:

[Service]
EnvironmentFile=/path/to/some/file

โดยเฉพาะอย่างยิ่งถ้าคุณมีการมอบหมายงานเท่านั้นและไม่มีไวยากรณ์เปลือกคุณสามารถใช้มันเป็น/etc/default/grubEnvironmentFile

ผ่านEnvironmentรายการ

ด้านบนสามารถทำได้โดยใช้การแทนที่ดังต่อไปนี้:

[Service]
Environment=FOO=bar

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

อ่านเพิ่มเติม

ผ่านกลไกนี้จะกลายเป็นเรื่องง่ายมากที่จะแทนที่systemdหน่วยเช่นเดียวกับการยกเลิกการเปลี่ยนแปลงดังกล่าว (เพียงแค่ลบไฟล์แทนที่) การตั้งค่าเหล่านี้ไม่ใช่การตั้งค่าเดียวที่สามารถแก้ไขได้

ลิงค์ต่อไปนี้จะมีประโยชน์:


1
คุณต้องล้างตัวแปรก่อนที่จะตั้งค่าสำหรับบริการที่ไม่ใช่ประเภทของภาพ นี่เป็นการแก้ไขปัญหาของฉัน
โคลิน

3
@MarkEdington จากsystemd.service(5)manpage, section on ExecStart: "Unless Type = is oneshot, ต้องระบุหนึ่งคำสั่งเมื่อใช้ Type = oneshot, อาจมีการระบุคำสั่งเป็นศูนย์หรือมากกว่านั้นคำสั่งอาจถูกระบุ คำสั่งหรือมิฉะนั้นคำสั่งนี้อาจถูกระบุมากกว่าหนึ่งครั้งที่มีผลกระทบเดียวกันหากสตริงว่างถูกกำหนดให้กับตัวเลือกนี้รายการคำสั่งที่จะเริ่มต้นจะถูกรีเซ็ตการกำหนดก่อนหน้าของตัวเลือกนี้จะไม่มีผล "
muru

1
@Orient คุณสามารถsudo rmแทนที่ไฟล์แล้วsystemctl daemon-reloadหรือคุณสามารถsystemctl editและแทนที่ทุกอย่างในการแทนที่ด้วยความคิดเห็น #ความคิดเห็นในแฟ้มบริการเริ่มต้นด้วย
muru

3
@Orientsystemctl revert foo
Ayell

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