Автоматический запуск программ на Raspberry Pi
Существует множество способов автоматического запуска программ на Raspberry Pi при загрузке или входе в систему. Есть cron, init, Gnome Scheduler и другие. Однако последняя версия Raspbian включает ещё один инструмент, называемый systemd.
systemd
systemd — это набор приложений, используемых для управления операционной системой. Мне он нравится тем, что можно настроить «сервис» (вашу программу), которым systemd будет автоматически управлять за вас. Так, например, если ваша программа аварийно завершится, systemd может перезапустить её. Это особенно полезно, если ваш Raspberry Pi используется для мониторинга чего-либо или записи измерений, и вы не хотите пропустить ни одного значения, или если вы используете робота на базе Raspberry Pi в соревновании, и аварийное завершение управляющей программы означало бы потерю очков!
Настройка
В этом примере мы будем запускать Python-скрипт каждый раз при загрузке вашего Raspberry Pi. Этот скрипт используется для управления роботом, у которого нет экрана или клавиатурного ввода, поэтому автоматический запуск управляющей программы при загрузке Raspberry Pi просто необходим. Я поместил скрипт в домашнюю директорию пользователя pi:
/home/pi/DriveRobot.py
systemd использует конфигурационные файлы, называемые «unit-файлами», чтобы знать, что делать. Давайте создадим один для нашего робота. Откройте окно терминала и введите следующее:
sudo nano /lib/systemd/system/driverobot.service
Теперь введите следующее:
[Unit]
Description=DriveRobot Service
After=multi-user.target
[Service]
Type=idle
User=pi
ExecStart=/usr/bin/python3 /home/pi/DriveRobot.py
Restart=always
RestartSec=0
[Install]
WantedBy=multi-user.target
В этом unit-файле три секции:
Секция [Unit] содержит два значения:
Имя сервиса (
Description).Когда в процессе загрузки сервис должен быть запущен (
After). В данном случае он будет запущен после завершения процессаmulti-userв systemd — то есть на этапе, когда учётные записи пользователей доступны системе. Это происходит до загрузки рабочего стола Raspbian, поэтому если ваш Raspberry Pi загружается в режиме рабочего стола и вы хотите, чтобы ваша программа отображала пользовательский интерфейс на рабочем столе, вам нужно изменить это значение наgraphical.target.
Секция [Service] определяет, что будет запущено и что делать, если ваша программа аварийно завершится или выйдет.
Параметр
Typeсо значениемidleуказываетsystemdдождаться завершения всех остальных сервисов. Это делается для того, чтобы не замедлять загрузку.Userопределяет, под каким пользователем будет запущена программа. В данном случае это стандартный пользовательpi.ExecStart— это исполняемый файл для запуска. В данном случаеpython3, запускающий скриптDriveRobot.py. Обратите внимание, что необходимо указывать полный путь как к программе, которую вы запускаете (python3), так и к скрипту.Restartсо значениемalwaysуказываетsystemdотслеживать запущенный процесс, и если он остановится,systemdперезапустит его.RestartSecуказываетsystemdждать 0 секунд перед перезапуском программы, если она завершилась.
Последняя секция, [Install], содержит директиву
WantedBy. Она указывает, что сервис driverobot будет нежёстко привязан к сервису multi-user — он будет запущен после успешного старта сервиса multi-user.
После сохранения файла необходимо изменить права доступа unit-файла командой:
sudo chmod 644 /lib/systemd/system/driverobot.service
Это сделает его доступным для чтения всем, а для записи — только владельцу.
Настройка systemd
Теперь, когда вы создали unit-файл, необходимо сообщить systemd о нём и включить его, чтобы сервис driverobot запускался каждый раз при загрузке Raspberry Pi. Сделайте это с помощью:
sudo systemctl daemon-reload
sudo systemctl enable driverobot.service
После чего вы можете перезагрузить ваш Raspberry Pi.
Проверка статуса сервиса driverobot
После завершения перезагрузки вашего Raspberry Pi ваш скрипт должен уже работать. Вы можете проверить это с помощью команды systemctl:
sudo systemctl status driverobot.service
Она должна вернуть что-то вроде этого:
Тестирование «аварийного завершения»
Полезно проверить, будет ли systemd обрабатывать аварийное завершение кода. Чтобы сымитировать это, нужно «убить» процесс python, выполняющий ваш скрипт. Чтобы узнать идентификатор процесса, выполните следующее:
ps -ax | grep driverobot
Эта команда должна вернуть две строки — одну для процесса python3 и одну для только что выполненного grep. Идентификатор процесса (pid) — это первое число в строке.
Чтобы остановить ваш код, выполните следующее:
kill -9 xxx
Где xxx — это идентификатор процесса, который вы только что нашли.
Теперь проверьте, был ли ваш код перезапущен, выполнив это снова:
ps -ax | grep driverobot
Если systemd корректно выполнил свою работу, вы должны увидеть процесс python3, который всё ещё работает, но на этот раз с другим идентификатором процесса.
Заключение
Теперь у вас есть возможность запускать ваш код или любую программу каждый раз при загрузке вашего Raspberry Pi и поддерживать её работу всё время!