मैं सिस्टम के साथ शटडाउन पर बाकी सब से पहले एक स्क्रिप्ट कैसे चलाऊं?


17

नोट: संक्षेप में तैयार किया गया प्रश्न नीचे पाया जा सकता है।

मेरे पास एक स्क्रिप्ट है जो बाहरी USB ड्राइव पर मेरी फ़ाइलों का बैकअप बनाती है। मेरे द्वारा बनाए गए नए डेटा की मात्रा के आधार पर, इसे निष्पादित करने में कुछ समय लग सकता है। मैं इसे सिस्टम के हर शटडाउन पर स्वचालित रूप से चलाना चाहता हूं।

मैं नवीनतम अपडेट (सिस्टमड) के साथ फेडोरा 23 का उपयोग कर रहा हूं।

मैंने इसे कई तरीकों से हासिल करने की कोशिश की, लेकिन मैं इसे काम नहीं कर पाया।

StopExec के साथ लंबे समय तक चलने की प्रक्रिया

autobackup.service:

[Unit]
Description=Slow backup script
Requires=local-fs.target

[Service]
ExecStart=/bin/true
ExecStop=/etc/systemd/system/do_backup.sh
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=multiuser.target

मैंने इसे सक्रिय किया systemctl enable autobackup.serviceऔर इसके साथ शुरुआत की systemctl start autobackup.service

मेरे बूट लॉग का हिस्सा ( journalctl -b-1):

Dez 22 17:45:27 localhost systemd[1]: Unmounted /mnt/BACKUP.
Dez 22 17:45:27 localhost do_backup.sh[4296]: At subvol /home/BACKUP.2015_12_22-17_45_25
Dez 22 17:45:27 localhost do_backup.sh[4296]: ERROR: parent subvol is not reachable from inside the root subvol.
Dez 22 17:45:27 localhost do_backup.sh[4296]: At snapshot BACKUP.2015_12_22-17_45_25
Dez 22 17:45:27 localhost do_backup.sh[4296]: ERROR: failed to dump stream. Broken pipe
Dez 22 17:45:27 localhost systemd[1]: autobackup.service: Control process exited, code=exited status=1
Dez 22 17:45:27 localhost systemd[1]: Stopped Slow backup script.
Dez 22 17:45:27 localhost systemd[1]: autobackup.service: Unit entered failed state.

ध्यान दें कि मैंने बीच में कुछ भी छोटा नहीं किया था, यह वास्तव में स्क्रिप्ट शुरू होने से पहले अनमाउंट / mnt / BACKUP था, मजेदार संयोग है।

Shutdown.target से पहले

autobackup.service:

[Unit]
Description=Slow backup script
DefaultDependencies=no
Before=shutdown.target

[Service]
ExecStart=/etc/systemd/system/do_backup.sh
Type=oneshot

systemctl edit shutdown.target

[Unit]
Requires=autobackup.service

आउटपुट मूल रूप से समान है।

समस्या

मुझे लगता है कि समस्या यह है कि systemd दोनों मामलों में अन्य सभी शटडाउन स्क्रिप्ट के समानांतर मेरी स्क्रिप्ट शुरू करता है, जो BACKUP को अनमाउंट करता है और पाइप के बुनियादी ढांचे को निष्क्रिय करता है (एक और त्रुटि जो मुझे कभी-कभी मिली, जब अनमाउंट काफी तेज नहीं था)।

प्रश्न

मैं अपनी स्क्रिप्ट को शटडाउन पर शुरू करने के लिए पहले से कैसे सिखा सकता हूं, जब तक यह बाहर नहीं निकलता है और तब तक शटडाउन की बाकी स्क्रिप्ट / टारगेट / यूनिट / जो भी हो, उसे शुरू करना है?

जवाबों:


12

सेवा फ़ाइलों को बनाने या संपादित करने की आवश्यकता नहीं है। बस में अपनी स्क्रिप्ट ड्रॉप

/usr/lib/systemd/system-shutdown/

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

वास्तविक सिस्टम हाल्ट / पॉवरऑफ़ / रिबूट / केक्सेक सिस्टमड-शटडाउन को निष्पादित करने से तुरंत पहले सभी निष्पादक / usr / lib / systemd / system-shutdown / चलाएंगे और उनमें से एक तर्क पास करेंगे: या तो "हॉल्ट", "पावरऑफ़", "रिबूट" "या" kexec ", चुने हुए कार्रवाई पर निर्भर करता है। इस निर्देशिका में सभी निष्पादनों को समानांतर में निष्पादित किया जाता है, और सभी निष्पादनयोग्य समाप्त होने से पहले कार्रवाई का निष्पादन जारी नहीं होता है।

मैं इसका उपयोग केवल पीसी स्पीकर को बीप करने के लिए करता हूं।


2
क्या आपको यह निर्देशिका करनी थी? मेरे पास यह न तो उबंटू 16.04 पर है और न ही रास्पबियन (जेसी) - दोनों सिस्टम आधारित हैं।
WoJ

2
डेबियन सिस्टम अलग पथ का उपयोग करते हैं /lib/systemd/system-shutdown/। और इसके अलावा पता है कि इन लिपियों को शटडाउन में बहुत देर से निष्पादित किया जाता है, फ़ाइल सिस्टम पहले से ही रीड-ओनली माउंट होने के बाद। इसलिए फ़ाइल सिस्टम में कोई भी लिखने की पहुंच तब तक विफल रहेगी जब तक कि रीड-राइट ( mount -oremount,rw /) के रूप में रिमूव न हो जाए । देखें कि रीबूट या शटडाउन में / usr / lib / systemd / system-shutdown / में स्क्रिप्ट कैसे निष्पादित करें?
फ्रैंक

9
ओपी ने शटडाउन पर "बाकी सब से पहले" निष्पादित स्क्रिप्ट के लिए कहा। सिस्टम-बंद लिपियों को कर्नेल को मारने से तुरंत पहले, बाकी सब के बाद निष्पादित किया जाता है।
ग्रेग अलेक्जेंडर

11

मैं समझ गया!

StopExec के साथ लंबे समय तक चलने वाली प्रक्रिया का समाधान करें और इसे इस तरह संशोधित करें:

autobackup.service:

[Unit]
Description=Slow backup script
RequiresMountsFor=/mnt/BACKUP /home

[Service]
ExecStop=/etc/systemd/system/do_backup.sh
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

नोट लाइन:

RequiresMountsFor=/mnt/BACKUP /home

यह उम्मीद के मुताबिक काम करता है।


2
आपको ऐसा करने की आवश्यकता नहीं है systemctl editsystemctl enable autobackupएक ही प्रभाव है और अधिक मुहावरेदार है, और काम करना चाहिए क्योंकि आपके पास पहले से ही [Install]आपकी इकाई में अनुभाग है। आपको लक्ष्य नाम में उस टाइपो को सुधारना होगा, हालाँकि। ;)
स्टीफन मेजवस्की

OMG मैं अपनी बैकअप स्क्रिप्ट को कॉल करने के लिए एक समाधान के लिए इतनी लंबी खोज कर रहा था, क्योंकि कोई भी ड्राइव अनमाउंट है। धन्यवाद!
डीनरेसिन

2
यह मेरे लिए काम नहीं करता है। मेरे पास कोई माउंट नहीं है, मैं सिर्फ यह सुनिश्चित करना चाहता हूं कि अन्य इकाइयों को बंद करने से पहले मेरी स्क्रिप्ट चलती है।
2rs2ts
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.