จะรันสคริปต์ด้วย systemd ได้อย่างไรก่อนปิดเครื่อง?


58

ฉันต้องใส่อะไรใน[install]ส่วนเพื่อให้ systemd ทำงาน/home/me/so.plก่อนปิดและก่อนที่/proc/self/net/devจะถูกทำลาย?

[Unit]
Description=Log Traffic

[Service]
ExecStart=/home/me/so.pl

[Install]
?

คำตอบ:


66

วิธีแก้ปัญหาที่แนะนำคือการเรียกใช้หน่วยบริการเป็นบริการปกติ - ดูที่[Install]ส่วน ดังนั้นทุกอย่างจะต้องมีการคิดย้อนกลับการพึ่งพาเช่นกัน เพราะคำสั่งปิดเป็นลำดับเริ่มต้นย้อนกลับ ExecStop=นั่นเป็นเหตุผลที่สคริปต์จะต้องมีการวางไว้ใน

วิธีแก้ปัญหาต่อไปนี้ใช้ได้กับฉัน:

[Unit]
Description=...

[Service]
Type=oneshot
RemainAfterExit=true
ExecStop=<your script/program>

[Install]
WantedBy=multi-user.target

RemainAfterExit=trueเป็นสิ่งจำเป็นเมื่อคุณไม่มีการExecStartกระทำ

หลังจากที่สร้างไฟล์ให้แน่ใจว่าการและsystemctl daemon-reloadsystemctl enable yourservice --now

ฉันเพิ่งได้รับจาก systemd IRC เครดิตจะไป mezcalero


6
ที่อูบุนตู 16.04 ExecStart=/bin/trueคุณต้องมี
niels

3
ข้อสันนิษฐานของฉันต่อWHY RemainAfterExit=trueเป็นสิ่งจำเป็นเมื่อไม่มีExecStartอยู่เพราะsystemdจะไม่พยายามเรียกใช้ExecStopหากคิดว่าบริการไม่ทำงาน RemainAfterExit=trueทำให้เกิดsystemdการเชื่อว่าบริการที่ทำงานจึงก่อให้เกิดการทำงานExecStopที่ปิด
เฟลิเป้อัลวาเรซ

1
มีอยู่แล้วเพื่อให้แน่ใจว่าสคริปต์นี้จะทำงานและสมบูรณ์ก่อนเซสชันผู้ใช้และกระบวนการของผู้ใช้จะถูกยกเลิก?
richmb

@richmb ไม่เลย จากเอกสาร :Note that it is usually not sufficient to specify a command for this setting that only asks the service to terminate (for example, by queuing some form of termination signal for it), but does not wait for it to do so.
svenwltr

ฉันได้ลองทำสิ่งนี้และทำซ้ำหลาย ๆ อย่างแล้ว แต่มันไม่สามารถใช้กับ Debian Stretch ได้
2rs2ts

8

เท่าที่ฉันเห็นนี่เป็นสิ่งที่ฉันต้องการ (แต่ฉันไม่รู้ว่าทำไม)

[Unit]
Description=Log Traffic
DefaultDependencies=no
Before=shutdown.target reboot.target halt.target


[Service]
ExecStart=/usr/local/bin/perl /home/me/log_traffic.pl --stop
Type=oneshot

3
มันเกิดขึ้นกับการทำงานเนื่องจาก 2 สิ่ง: 1) DefaultDependencies = ไม่ทำให้ละเว้นการอ้างอิงทั้งหมดและเรียกใช้ "ตอนแรก" ที่เริ่มต้นและ "สุดท้าย" ที่หยุดเสมอเคารพ "ก่อน" และ "หลัง" 2) มันเกิดขึ้นก่อนที่จะมีประโยคก่อนในการปิด / รีบูต / หยุดเป้าหมายดังนั้นมันจะทำงานก่อนที่จะถึงการปิด / รีบูต / halt เมื่อถึงจุดหยุด (เพราะมันจะทำงานเมื่อหยุดเท่านั้น
RDP

คุณอาจต้องการเพิ่มลงkexec.targetในบิตก่อนหน้า
hanetzer

สิ่งนี้ไม่ได้ผลสำหรับฉัน
Bug Killer

ฉันไม่เห็นว่ามันจะทำงานได้อย่างไรถ้าคุณยังเพิ่มWantedBy=shutdown.target reboot.target halt.targetใน[Unit]ส่วน Before=& After=ไม่เปลี่ยนการพึ่งพา
rsaw

1
@FelipeAlvarez: ฉันได้ลบความคิดเห็นของฉัน
sid_com

7
  • ในการรันบริการทันทีก่อนที่จะเริ่มบริการ reboot / shutdown / halt / kexec ใด ๆ (เช่นในช่วงเวลาสุดท้ายก่อนที่ระบบไฟล์รูทจะกลายเป็นแบบอ่านอย่างเดียว) อีกครั้งใช้บริการ config นี้:

    [Unit]
    Description=Save system clock on shutdown
    DefaultDependencies=no
    After=final.target
    
    [Service]
    Type=oneshot
    ExecStart=/usr/lib/systemd/scripts/fake-hwclock.sh save
    
    [Install]
    WantedBy=final.target
    

    เปิดใช้งานด้วย:

    systemctl enable my_service.service
    
  • หากต้องการรันสคริปต์ก่อนที่จะรีบูต / ปิดระบบ / halt / kexec จริง (เมื่อคุณไม่สามารถเขียนไปยังระบบไฟล์รูทได้เนื่องจากมีการติดตั้งซ้ำแบบอ่านอย่างเดียว) ให้เพิ่มสคริปต์นี้ลงใน/usr/lib/systemd/system-shutdownไดเร็กทอรี

    ทันทีก่อนที่จะเรียกใช้ระบบจริงหยุด / poweroff / reboot / kexec systemd-shutdown จะเรียกใช้งาน executables ทั้งหมดใน / usr / lib / systemd / system-shutdown / และส่งหนึ่งอาร์กิวเมนต์ไปยังพวกเขา: ทั้ง "หยุด", "poweroff", "poweroff" "หรือ" kexec "ขึ้นอยู่กับการกระทำที่เลือก ไฟล์เรียกทำงานทั้งหมดในไดเร็กทอรีนี้ถูกเรียกใช้งานแบบขนานและการดำเนินการของแอ็คชันจะไม่ต่อเนื่องก่อนที่ไฟล์เรียกทำงานทั้งหมดจะเสร็จสิ้น

ดูเพิ่มเติมที่:

https://www.freedesktop.org/software/systemd/man/bootup.html

https://www.freedesktop.org/software/systemd/man/systemd-halt.service.html


1
final.targetฉันต้องการที่จะดำเนินการบางสิ่งบางอย่างที่ใกล้ที่สุดหลังจากที่เริ่มต้นการรีบูตวิธีก่อน $ sudo rebootดีฉันชอบที่มันเป็นสิ่งแรกที่ถูกดำเนินการหลังจากที่ผู้ใช้ทำ
Jaime Hablutzel

5

ฉันไม่แน่ใจทั้งหมด แต่ฉันไม่คิดว่าคุณต้องการส่วนการติดตั้งแม้ว่าฉันจะเพิ่มมันอย่างชัดเจน ฉันยังไม่ได้ทดสอบ แต่ฉันคิดว่าควรช่วยให้คุณเริ่มต้น:

[Unit]
Description=Log Traffic
Requires=network.target
After=network.target
Before=shutdown.target
DefaultDependencies=no

[Service]
ExecStart=/home/me/so.pl
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=shutdown.target

เมื่อฉันลองทำสิ่งนี้สคริปต์จะถูกเรียกใช้งานไม่นานหลังจากเริ่มต้น (บูต)
sid_com

@sid_com หลังจากอ่านthread.gmane.org/gmane.comp.sysutils.systemd.devel/4515/…ลองเพิ่ม DefaultDependencies = no และอาจลบหัวข้อการติดตั้งออก มิฉะนั้นอาจช่วยในการรีโมตบรรทัด after / ต้องการ
Ulrich Dangel
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.