ฉันจะทำให้บริการ systemd ของฉันทำงานผ่านผู้ใช้เฉพาะและเริ่มบูตได้อย่างไร


132

ฉันเพิ่งอัพเกรดจากเซิร์ฟเวอร์ Ubuntu ที่ 14 เป็นเวอร์ชั่น 15 ฉันมีปัญหาในการทำให้สคริปต์พุ่งพรวดทำงานหลังจากการอัพเกรดและอ่านว่า systemd เป็นค่าเริ่มต้นใหม่ ฉันอยู่ไกลจากผู้เชี่ยวชาญของ linux ดังนั้นโปรดไปกับฉันได้อย่างง่ายดาย :-)

นี่คือสิ่งที่สคริปต์พุ่งพรวดของฉันมาก่อน:

description "NZBGet upstart script"

setuid robert
setgid robert

start on runlevel [2345]
stop on runlevel [016]

respawn

expect fork

script
    exec nzbget -D
end script

pre-stop script
    exec nzbget -Q
end script

จากหน้าเริ่มต้นสู่หน้า systemd wikiฉันใช้ตารางที่จัดเตรียมไว้เพื่อจับคู่สิ่งต่าง ๆ ให้ใกล้เคียงที่สุดเท่าที่จะทำได้ในไฟล์บริการ systemd ใหม่ของฉัน:

[Unit]
Description=NZBGet Service

[Service]
Type=forking
ExecStart=/usr/local/bin/nzbget -D
ExecStop=/usr/local/bin/nzbget -Q
Restart=on-failure

/home/robert/.config/systemd/user/nzbget.serviceไฟล์นี้จะอยู่ที่ ในการเริ่มบริการด้วยตนเองฉันได้ทำ:

$ systemctl --user start nzbget

มันใช้งานได้ดี อย่างไรก็ตามเมื่อฉันออกจากระบบเซสชัน SSH บริการจะปิดตัวลง นอกจากนี้มันไม่ได้เริ่มต้นในการบูทหรือเข้าสู่ระบบผู้ใช้ ฉันต้องการให้มันทำงานเหมือนที่เคยทำในฐานะบริการพุ่งพรวด: ฉันต้องการให้มันเริ่มต้นตอนบูททำงานอย่างต่อเนื่องและในฐานะผู้ใช้ที่เฉพาะเจาะจง

ฉันต้องทำอะไรเพื่อให้ได้การกำหนดค่านี้

คำตอบ:


163

ปัญหาแรก

คุณสามารถระบุคำสั่งUser=และGroup=ใน[Service]ส่วนของไฟล์หน่วย

ปัญหาที่สอง

เพื่อให้บริการทำงานในการบูตคุณไม่ควรใส่ไว้ในโฟลเดอร์บ้านของคุณ /etc/systemd/system/แต่วางไว้ใต้ นี่คือโฟลเดอร์ที่ผู้ดูแลระบบใช้เพื่อเพิ่มบริการใหม่ของระบบ

โฟลเดอร์อื่น ๆ ได้แก่ :

  • /usr/lib/systemd/system/มีไว้สำหรับแพคเกจที่ต้องการติดตั้งไฟล์หน่วยแม้ว่าภายใต้ Debian และ Ubuntu โฟลเดอร์นั้นเป็น/lib/systemd/system/เพราะความหลากหลายbinและlibโฟลเดอร์ยังไม่ได้ถูกรวมเข้ากับ/usr/คำนำหน้าแบบรวม
  • /usr/local/systemd/system/ ใช้สำหรับติดตั้งหน่วยโดยแพ็คเกจที่คอมไพล์แล้ว

ทดสอบเครื่อง

เมื่อไฟล์หน่วยอยู่ในตำแหน่งที่เหมาะสมคุณสามารถลองเริ่มหน่วยทันทีโดยพิมพ์systemctl start <UNIT_FILENAME>ตามปกติ มันควรจะทำงานได้โดยไม่ต้องพิมพ์พา ธ เต็มของหน่วย ไม่จำเป็นต้องระบุนามสกุลหากเป็น.serviceเช่นนั้น

เปิดใช้งานเครื่อง

ก่อนที่คุณจะสามารถเปิดใช้งานหน่วยของคุณคุณจะต้องเพิ่มส่วนตามที่คุณควรเพิ่มคำสั่ง[Install] WantedBy=multi-user.targetคำสั่งนี้ระบุขั้นตอนของกระบวนการบูทเครื่องระหว่างที่ควรเริ่มบริการ (ถ้าเปิดใช้งาน) multi-user.targetเหมาะสมสำหรับบริการส่วนใหญ่

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


สิ่งนี้ใช้ได้ผล ฉันต้องระบุเส้นทางที่แน่นอนไปยังชื่อไฟล์บริการในsystemctl enableคำสั่ง แต่นี่ไม่ชัดเจนสำหรับฉันในตอนแรก การเปิดใช้งานทำให้ฉันได้รับคำเตือนบางอย่างเกี่ยวกับ[Install]ส่วนที่ขาดหายไป ฉันไม่สนใจ แต่ฉันไม่แน่ใจว่ามันจะส่งผลกระทบต่อความสามารถในการเริ่มต้นเวลาบูตหรือไม่
void.pointer

2
Installเตือนเป็นจริงสิ่งที่สำคัญจริงๆ มันจะไม่เริ่มต้นการบูทโดยไม่มีWantedBy=multi-user.targetอยู่ใน[Install]ส่วน หลังจากที่เพิ่มนี้ไปยัง.serviceไฟล์แล้วคุณสามารถenableมัน
void.pointer

4
ฉันขอโทษที่ออกจากคำตอบแบบอัตโนมัติเป็นเวลานาน ฉันแก้ไขตำแหน่งที่ไฟล์ยูนิตควรไปเพิ่มข้อมูลที่หายไปเกี่ยวกับ[Install]ส่วน หวังว่าตอนนี้มันจะมีประโยชน์มากขึ้นสำหรับทุกคนที่มองหามัน
Yamaho

5
สิ่งนี้จะกลายเป็นเรื่องง่ายขึ้นเมื่อชื่อผู้ใช้ถูกสร้างเทมเพลตนั่นคือบริการของคุณถูกกำหนดด้วยชื่อไฟล์ในรูปแบบsomething@.serviceจากนั้นenabled เช่นsomething@username.serviceการตั้งค่าจะกลายเป็นUser=%iความหมายว่าผู้ใช้ไม่ได้เข้ารหัสยากและผู้ใช้หลายคนสามารถใช้ข้อกำหนดเดียวกัน ตัวอย่าง.
Walf

1
มันจะเริ่มหรือไม่ถ้าฉันวางไว้ข้างใต้/etc/systemd/user/?
Khurshid Alam

46

คุณอาจสนใจใช้ฟังก์ชัน "user lingering" ของ systemd loginctl enable-linger USERNAMEมันถูกเปิดใช้งานผ่านทาง

มันทำให้ผู้จัดการฝ่ายบริการแยกต่างหากสำหรับผู้ใช้ที่เกี่ยวข้องกำลังเริ่มต้นตอนบูทดังนั้นหน่วยที่ผู้ใช้กำหนดของคุณ~/.config/systemd/userจะถูกหยิบขึ้นมาและประมวลผลเมื่อบูตและเวลาปิดเครื่องตามการกำหนดค่าบริการของคุณ

นอกจากนี้คุณยังสามารถใช้systemctl --userสำหรับการจัดการและกำหนดค่าบริการซึ่งจะทำงานกับผู้จัดการบริการของผู้ใช้ไม่ใช่ระบบใดระบบหนึ่ง


6
systemctl --userเป็นการค้นพบที่ยอดเยี่ยม ขอบคุณ!
Anwar

@byteborg บางทีคุณสามารถมีส่วนร่วมกับunix.stackexchange.com/questions/409900/… ? ฉันต้องการการพึ่งพา PostgreSQL ในการให้บริการผู้ใช้ แต่ฐานข้อมูลยังคงให้บริการระบบไม่ใช่ผู้ใช้
Michał F

1
เมื่อบริการกำลังทำงานมีเทคนิคใดบ้างที่สามารถอนุญาตให้ผู้ใช้เห็นบันทึกของบริการ ผู้ใช้ที่ไม่มีสิทธิพิเศษจะไม่สามารถเข้าถึง / var / log / syslog
mpr

2
โปรดทราบว่าsystemctl --userดูเหมือนจะไม่ทำงานสำหรับเซสชัน SSH
Mark K Cowan

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