วิธีดำเนินการต่อสคริปต์หลังจากรีบูตเครื่อง?


18

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

sudo reboot

เมื่อเครื่องกลับมาทำงานจะมีงานอีกมากที่สคริปต์นี้ต้องทำ ฉันจะกำหนดค่าบางสิ่งเพื่อทำงานในสคริปต์นี้ต่อไปได้อย่างไร

ฉันสมมติว่ามีบางที่ที่ฉันสามารถเขียนเชลล์สคริปเพื่อที่มันจะถูกประหารชีวิตในการรีบูทครั้งต่อไป สถานที่ดังกล่าวอยู่ที่ไหน ฉันเห็นว่า cron มีคำสั่ง @reboot ฉันรู้ด้วยเช่นกันว่าบริการต่างๆของ Apache เริ่มขึ้นจากการบูทโดยคนธรรมดา สิ่งเหล่านี้จะเป็นกลไกที่เหมาะสมหรือไม่? ถ้าเป็นเช่นนั้นจะทริกเกอร์อย่างไร?

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

คำถามนี้ถามเกี่ยวกับวิธีบันทึกสถานะแอปพลิเคชันของคุณหลังจากรีบูต สคริปต์ของฉันไม่มีสถานะมากนักดังนั้นฉันจึงสามารถจัดการได้ ฉันแค่ต้องรู้วิธีที่จะให้สคริปต์นี้กระตุ้นให้บางสิ่งบางอย่างทำงานหลังจากรีบูตครั้งถัดไป

รุ่นเฉพาะของฉันคือ Ubuntu Linux 14.04 สคริปต์ดั้งเดิมเริ่มต้นบนบรรทัดคำสั่งโดยผู้ดูแลระบบ (ต่างจากการเรียกใช้จาก cron)


ควรเริ่มระบบใหม่ภายในสคริปต์ก็ต่อเมื่อคุณไม่สามารถหลีกเลี่ยงได้ ตัวอย่างเช่นการติดตั้งเคอร์เนลใหม่ ฉันแน่ใจว่าคุณสามารถทำงานของคุณได้โดยไม่ต้องรีบูท คุณสามารถระบุสาเหตุที่คุณต้องการรีบูตได้หรือไม่?
โกลาหล

1
สคริปต์นี้ติดตั้งเคอร์เนลใหม่ (หรือเรียกว่าอัพเกรด apt ซึ่งอาจทำเช่นนั้น) นอกจากนี้ยังตรวจสอบด้วยว่าดูว่าจำเป็นต้องรีบูตจริงหรือไม่ก่อนทำการรีบูต
Stephen Ostermiller

"ควรใช้การรีบูตภายในสคริปต์เฉพาะเมื่อคุณไม่สามารถหลีกเลี่ยงได้" - @chaos ทำไม
John Red

คำตอบ:


16

บนระบบสิ่งเดียวที่คงอยู่จริงๆคือไฟล์ นั่นเป็นสิ่งที่คุณควรใช้ นี่คือวิธีการแก้ปัญหาโดยใช้สคริปต์ init.d

ลองพิจารณาสคริปต์ (ง่าย) ต่อไปนี้/etc/init.d/myupdate:

#! /bin/sh

### BEGIN INIT INFO
# Provides:          myupdate
### END INIT INFO

PATH=/sbin:/bin:/usr/sbin:/usr/bin

case "$1" in
    start)
        /path/to/update/script
        ;;
    stop|restart|reload)
        ;;
esac

หากคุณเปิดใช้งานด้วยupdate-rc.d myupdate defaultsการstartดำเนินการจะถูกดำเนินการเมื่อบูต ตอนนี้เมื่อสคริปต์อัปเดตของคุณร้องขอให้รีบูต:

touch /var/run/rebooting-for-updates
sudo reboot

ด้วยโซลูชันนี้คุณสามารถแบ่งสคริปต์อัปเดตของคุณเป็นสองส่วน:

before_reboot(){
    # Do stuff
}

after_reboot(){
    # Do stuff
}

if [ -f /var/run/rebooting-for-updates ]; then
    after_reboot
    rm /var/run/rebooting-for-updates
    update-rc.d myupdate remove
else
    before_reboot
    touch /var/run/rebooting-for-updates
    update-rc.d myupdate defaults
    sudo reboot
fi

มันจะรันbefore_rebootส่วนของรหัสสร้างไฟล์/var/runและรีบูต เมื่อบูตสคริปต์ที่จะถูกเรียกอีกครั้ง แต่เนื่องจากไฟล์ที่มีอยู่จะถูกเรียกแทนafter_rebootbefore_reboot

โปรดทราบว่าupdate-rc.dต้องใช้สิทธิ์พิเศษ

โดยไม่ใช้ไฟล์ (จากความคิดเห็นของStephen Ostermiller ):

หากคุณคุ้นเคยกับgetoptsยูทิลิตี้นี้คุณอาจต้องการใช้ตัวเลือกแทนไฟล์ ในสคริปต์เริ่มต้นให้เรียกใช้สคริปต์ด้วย:

/path/to/update/script -r

และในสคริปต์ของคุณให้ตรวจสอบตัวเลือกแทนไฟล์ โทรสคริปต์ของคุณเมื่อไม่มีตัวเลือกและ init.d -rจะเรียกมันอีกครั้งในการบูตครั้งนี้ด้วย

# Set AFTER_REBOOT according to options (-r).

if [ "x$AFTER_REBOOT" = "xyes" ]; then
    # After reboot
else
    # Before reboot
fi

คุณจะพบข้อมูลเพิ่มเติมเกี่ยวกับการจัดการตัวเลือกที่นี่ (สำหรับตัวเลือกสั้นเท่านั้น) ฉันยังแก้ไขสคริปต์ของฉันด้วยการเรียกร้องupdate-rc.dให้ทำงานนี้เป็นครั้งเดียว (จากความคิดเห็นอื่น)


2
มันอาจจะง่ายที่จะเรียก/path/to/update/script --after-rebootจากมากกว่าอาศัยการปรากฏตัวของ/etc/init.d/myupdate /var/run/rebooting-for-updatesจากนั้นมันจะมีอาร์กิวเมนต์ต่างกันเมื่อเรียกใช้โดยตรงกับเรียกเมื่อบูต
Stephen Ostermiller

นีซไม่ได้คิดเกี่ยวกับตัวเลือก อนุญาตให้ฉันแก้ไข;)
John WH Smith

1
นอกจากนี้เนื่องจากเป็นงานครั้งเดียวฉันอาจต้องการเพิ่มupdate-rc.d myupdate defaultsและupdate-rc.d myupdate removeเข้าไปในสคริปต์ของตัวเองเช่นเดียวกับการเขียนและลบ/etc/init.d/myupdateเพื่อที่จะไม่ปล่อยให้ไฟล์นั่งอยู่รอบ ๆ
สตีเฟ่น Ostermiller

ฉันได้ติดตั้งและใช้งานได้ดี สิ่งเดียวที่ฉันจะเพิ่มคือระบบของฉัน Debian ต้องใช้รายการเพิ่มเติมในINIT INFOส่วน: wiki.debian.org/LSBInitScripts
Stephen Ostermiller

ฉันต้องการทำให้มันง่ายจริง ๆ ;) การเขียน init.d ที่เหมาะสมนั้นใช้เวลาเล็กน้อย แต่ฉันดีใจที่คุณได้รับข้อมูลเพิ่มเติม: สคริปต์เหล่านี้มีประโยชน์ทีเดียว
John WH Smith
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.