Анализ и современное решение
Скрипт является занятым циклом: он продолжает читать выводы GPIO снова и снова. Он не потребляет много памяти, но загружает процессор.
Вы должны установить вывод GPIO в режиме края. gpio
Утилита имеет wfi
(ожидание прерывания) команды , которые вы можете использовать , чтобы реагировать на спусковой крючок края. ( gpio wfi
не существовало назад, когда был задан вопрос.)
set -e
gpio mode 0 in
gpio wfi 0 rising
echo password | sudo -S reboot
Решение Python
Существует библиотека Python для доступа к GPIO , которая поддерживает граничный режим. Вот некоторый полностью непроверенный код Python, который должен делать то, что вы хотите.
#!/usr/bin/env python
import os
from RPi import GPIO
GPIO.wait_for_edge(0, GPIO.RISING)
system("sudo reboot")
Дополнительные подсказки раковины
(true)
может быть написано просто true
. Скобки создают подпроцесс, который совершенно не нужен.
`gpio read 0`
должно быть в двойных кавычках. Без кавычек вывод команды обрабатывается как список шаблонов имен файлов. В двойных кавычках вывод команды обрабатывается как строка. Всегда ставьте двойные кавычки вокруг подстановок команд и подстановок переменных: "$(some_command)"
, "$some_variable"
. Кроме того, вы должны использовать синтаксис, $(…)
а не `…`
: он имеет точно такое же значение, но синтаксис обратной кавычки имеет некоторые причуды синтаксического анализа, когда команда сложна. Таким образом:if [ "$(gpio read 0)" -eq 1 ]
Не помещайте пароль root в скрипт. Если скрипт выполняется от имени пользователя root, вам вообще не нужен sudo. Если сценарий не запущен от имени пользователя root, предоставьте пользователю, запускающему сценарий, разрешение на запуск sudo reboot
без указания пароля. Запустите visudo
и добавьте следующую строку:
userwhorunsthescript ALL = (root) NOPASSWD: /sbin/reboot ""
Обратите внимание, что если в файле sudoers есть запись для того же пользователя, для которой требуется пароль, то NOPASSWD
запись должна идти после.
Как только вы запускаете перезагрузку, вам не нужно прерывать цикл, система все равно остановится.
Если вы решите продолжать использовать этот сценарий оболочки, а ваша версия gpio
слишком старая, чтобы иметь wfi
подкоманду, вот улучшенная версия, которая проверяет состояние кнопки каждую секунду. Обратите внимание, что, поскольку пин-код считывается только один раз в секунду, это означает, что вам нужно удерживать кнопку нажатой не менее одной секунды, чтобы быть уверенным, что событие зафиксировано.
gpio mode 0 in
while sleep 1; do
if [ "$(gpio read 0)" -eq 1 ]; then
reboot
fi
done &