ฉันจะรันสคริปต์ Bash ก่อนปิดหรือรีบูต Raspberry Pi (ใช้งาน Raspbian) ได้อย่างไร

ฉันต้องการเรียกใช้สคริปต์ Bash ก่อนที่จะปิดระบบหรือรีบูต Pi ของฉัน (ใช้งาน Raspbian ล่าสุดซึ่งเป็นอนุพันธ์ของ Debian)

เช่น. ถ้าฉันพิมพ์ sudo shutdown now หรือ sudo restart now ใน command prompt ก็ควรจะรันสคริปต์ Bash ของฉันก่อนที่จะดำเนินการปิดระบบ/รีบูตต่อ

ฉันสร้างสคริปต์ง่ายๆ สำหรับการทดสอบเท่านั้น เพื่อให้แน่ใจว่าวิธีการทำงานก่อนที่จะไปยุ่งกับการเขียนสคริปต์จริง:

#!/bin/bash
touch /home/pi/ShutdownFileTest.txt

จากนั้นฉันคัดลอกไฟล์ (เรียกว่า CreateFile.sh) ไปที่ /etc/init.d/CreateFile จากนั้นฉันสร้าง symlink ใน /etc/rc0.d/ และ /etc/rc6.d/:

sudo ln -s /etc/init.d/CreateFile K99Dave

ฉันไม่แน่ใจว่าควรตั้งชื่อที่เหมาะสมสำหรับ symlink อย่างไร บางเว็บบอกว่า "ขึ้นต้นชื่อไฟล์ด้วยตัว K" บางเว็บก็บอกว่า "เริ่มต้นด้วยตัว S" บางเว็บก็บอกว่า "เริ่มต้นด้วย K99 เพื่อให้มันทำงานถูกเวลา"...

จริงๆ แล้วฉันได้ลองทำสิ่งต่อไปนี้ทั้งหมดแล้ว (ไม่ใช่ทั้งหมดในคราวเดียว แต่ทีละครั้ง):

sudo ln -s /etc/init.d/CreateFile S00Dave
sudo ln -s /etc/init.d/CreateFile S99Dave
sudo ln -s /etc/init.d/CreateFile K00Dave
sudo ln -s /etc/init.d/CreateFile K01rpa
sudo ln -s /etc/init.d/CreateFile K99Dave

หลังจากสร้างแต่ละ symlink แล้ว ฉันมักจะรัน:

sudo chmod a+x /etc/init.d/CreateFile && sudo chmod a+x /etc/rc6.d/<name of symlink>

จากนั้นฉันก็รีบูททุกครั้ง

แต่ละครั้ง ไฟล์ที่ /home/pi/ShutdownFileTest.txt ไม่ได้ถูกสร้างขึ้น สคริปต์ไม่ได้ถูกดำเนินการ

ฉันพบความคิดเห็นนี้ในโพสต์เก่าๆ โดยแนะนำว่า ข้างต้นเป็นวิธีการที่ล้าสมัย:

วิธีที่ทันสมัยในการทำเช่นนี้คือผ่าน systemd ดู "man systemd-shutdown" สำหรับรายละเอียด โดยพื้นฐานแล้ว ให้ใส่เชลล์สคริปต์ที่สามารถเรียกใช้งานได้ใน /lib/systemd/system-shutdown/ โดยจะมีการส่งผ่านอาร์กิวเมนต์เช่น "หยุด" หรือ "รีบูต" ซึ่งช่วยให้คุณสามารถแยกแยะกรณีต่างๆ ได้หากต้องการ

ฉันคัดลอกสคริปต์ของฉันไปที่ /lib/systemd/system-shutdown/, chmod +x'd แล้วรีบูท แต่ก็ยังไม่ประสบความสำเร็จ

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

ใครช่วยบอกฉันทีว่าฉันไปไหนผิด?

ขอบคุณล่วงหน้าเดฟ


person ZPMMaker    schedule 12.12.2018    source แหล่งที่มา


คำตอบ (2)


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

ดังนั้นจำเป็นต้องติดตั้งระบบไฟล์ที่จุดเริ่มต้นของสคริปต์และยกเลิกการต่อเชื่อมที่ส่วนท้ายจึงเป็นสิ่งที่จำเป็น

เพียงเพิ่ม:

mount -oremount,rw /

...ที่จุดเริ่มต้นของสคริปต์ (ใต้ #!/bin/bash)

...จากนั้นก็มีโค้ดของสคริปต์...

จากนั้นจบสคริปต์ด้วย:

mount -oremount,ro /

ดังนั้นสคริปต์ OP ควรเป็น:

#!/bin/bash
mount -oremount,rw /
touch /home/pi/ShutdownFileTest.txt
mount -oremount,ro /

...จากนั้นจะสร้างไฟล์ /home/pi/ShutdownFileTest.txt ก่อนปิดเครื่อง/รีบูต


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

โดยมีการอธิบายโดยละเอียดที่นี่ แต่โดยพื้นฐานแล้ว:

1: สร้างไฟล์ (ขอเรียกว่า example.service)

2: เพิ่มสิ่งต่อไปนี้ลงใน example.service:

[Unit]
Description=This service calls shutdownScript.sh upon shutdown or reboot.

[Service]
Type=oneshot
RemainAfterExit=true
ExecStop=/home/pi/shutdownScript.sh

[Install]
WantedBy=multi-user.target

3: ย้ายไปยังไดเร็กทอรีที่ถูกต้องสำหรับ systemd โดยเรียกใช้ sudo mv /home/pi/example.service /etc/systemd/system/example.service

4: ตรวจสอบให้แน่ใจว่าสคริปต์ที่จะเปิดใช้งานเมื่อปิดเครื่องมีสิทธิ์ที่เหมาะสม: chmod u+x /home/pi/shutdownScript.sh

5: เริ่มบริการ: sudo systemctl start example --now

6: ทำให้บริการเริ่มต้นโดยอัตโนมัติเมื่อบูต: sudo systemctl enable example

7: หยุดบริการ: sudo systemctl stop example

คำสั่งสุดท้ายนี้จะเลียนแบบสิ่งที่เกิดขึ้นตามปกติเมื่อระบบปิดตัวลง กล่าวคือ คำสั่งจะทำงาน /home/pi/shutdownScript.sh (โดยไม่ต้องปิดระบบจริง ๆ )

จากนั้นคุณสามารถรีบูตได้สองครั้งและควรจะทำงานได้ตั้งแต่การรีบูตครั้งที่สองเป็นต้นไป

แก้ไข: ไม่ ไม่ มันไม่ได้ มันใช้งานได้ในครั้งแรกที่ฉันทดสอบ แต่หยุดทำงานหลังจากนั้น ไม่แน่ใจว่าทำไม หากฉันทราบวิธีการทำงาน ฉันจะแก้ไขคำตอบนี้และลบข้อความนี้ (หรือหากมีคนอื่นรู้ โปรดอย่าลังเลที่จะแก้ไขคำตอบให้ฉัน)

person ZPMMaker    schedule 12.12.2018

เนื่องจากฉันไม่มีวุฒิภาวะมากพอที่จะโพสต์ความคิดเห็น นี่เป็นคำตอบใหม่ที่ฉันขอโทษ

ฉันเพิ่มขั้นตอนในคำตอบของ ZPMMaker และดูเหมือนว่าจะได้ผลสำหรับฉันเป็นอย่างน้อย

sudo chmod u+x /etc/systemd/system/example.service
person Torben Jakobsen    schedule 16.04.2019