Как запустить сценарий Bash перед выключением или перезагрузкой Raspberry Pi (работает с Raspbian)?

Я хочу запустить сценарий Bash до выключения или перезагрузки моего Pi (запустив последнюю версию Raspbian, производную от Debian).

например если я наберу sudo shutdown now или sudo reboot now в командной строке, он должен запустить мой сценарий Bash, прежде чем продолжить выключение/перезагрузку.

Я создал очень простой скрипт только для тестирования, чтобы убедиться, что метод работает, прежде чем я буду писать настоящий скрипт:

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

Затем я скопировал файл (с именем CreateFile.sh) в /etc/init.d/CreateFile. Затем я создал символические ссылки в /etc/rc0.d/ и /etc/rc6.d/:

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

Я не уверен, каким должно быть правильное имя для символической ссылки. Некоторые веб-сайты говорят: «Начинайте имя файла с 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

После создания каждой символической ссылки я всегда запускал:

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 и перезагрузился, но безуспешно.

Я отмечаю, что в приведенном выше комментарии говорится, что скрипту передается «остановка» или «перезагрузка» в качестве аргумента. Поскольку в обоих случаях он должен работать одинаково, я предполагаю, что ему не нужно иметь дело с этим аргументом. Я тоже не знаю, как справиться с этим аргументом, поэтому я не уверен, нужно ли мне что-то делать, чтобы это сработало или нет...

Может кто-нибудь, пожалуйста, скажите мне, где я ошибаюсь?

Заранее спасибо, Дэйв


person ZPMMaker    schedule 12.12.2018    source источник


Ответы (2)


Как оказалось, часть команды выключения уже выполнена (и размонтирована файловая система) до выполнения этих скриптов.

Следовательно, необходимо монтировать файловую систему в начале скрипта и размонтировать ее в конце.

Просто добавьте:

mount -oremount,rw /

... в начале скрипта (под #!/bin/bash)

...то есть код скрипта...

а затем завершите скрипт:

mount -oremount,ro /

Итак, сценарий ОП должен стать:

#!/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