Analyse und moderne Lösung
Das Skript ist eine Besetztschleife: Es liest immer wieder die GPIO-Pins. Es verbraucht nicht viel Speicher, hält aber die CPU beschäftigt.
Sie sollten den GPIO-Pin in den Edge-Modus versetzen. Das gpio
Dienstprogramm verfügt über einen wfi
Befehl (Warten auf Interrupt), mit dem Sie auf einen Flankentrigger reagieren können. ( gpio wfi
existierte nicht zurück, als die Frage gestellt wurde.)
set -e
gpio mode 0 in
gpio wfi 0 rising
echo password | sudo -S reboot
Eine Python-Lösung
Es gibt eine Python-Bibliothek für den GPIO-Zugriff , die den Edge-Modus unterstützt. Hier ist ein völlig ungetesteter Python-Code, der das tun soll, was Sie wollen.
#!/usr/bin/env python
import os
from RPi import GPIO
GPIO.wait_for_edge(0, GPIO.RISING)
system("sudo reboot")
Zusätzliche Shell-Tipps
(true)
könnte gerade geschrieben werden true
. Die Klammern erstellen einen Unterprozess, der völlig unnötig ist.
`gpio read 0`
sollte in doppelten Anführungszeichen stehen. Ohne Anführungszeichen wird die Ausgabe des Befehls als Liste von Platzhaltermustern für Dateinamen behandelt. Bei doppelten Anführungszeichen wird die Ausgabe des Befehls als Zeichenfolge behandelt. Setzen Sie immer doppelte Anführungszeichen um Befehlssubstitutionen und Variablensubstitutionen: "$(some_command)"
, "$some_variable"
. Sie sollten auch die Syntax verwenden $(…)
und nicht `…`
: Sie hat genau die gleiche Bedeutung, aber die Backquote-Syntax weist einige Parsing-Macken auf, wenn der Befehl komplex ist. Somit:if [ "$(gpio read 0)" -eq 1 ]
Fügen Sie das Root-Passwort nicht in das Skript ein. Wenn das Skript als root ausgeführt wird, benötigen Sie sudo überhaupt nicht. Wenn das Skript nicht als root ausgeführt wird, erteilen Sie dem Benutzer, der das Skript ausführt, die Berechtigung zum Ausführen, sudo reboot
ohne ein Kennwort anzugeben. Führen visudo
Sie die folgende Zeile aus und fügen Sie sie hinzu:
userwhorunsthescript ALL = (root) NOPASSWD: /sbin/reboot ""
Beachten Sie, dass der Eintrag folgen NOPASSWD
muss , wenn in der sudoers-Datei ein Eintrag für denselben Benutzer vorhanden ist, für den ein Kennwort erforderlich ist .
Sobald Sie einen Neustart auslösen, müssen Sie die Schleife nicht mehr unterbrechen, das System stoppt trotzdem.
Wenn Sie dieses Shell-Skript weiterhin verwenden möchten und Ihre Version von gpio
zu alt ist, um den wfi
Unterbefehl zu verwenden, finden Sie hier eine verbesserte Version, die nur den Schaltflächenstatus jede Sekunde überprüft. Da der Pin nur einmal pro Sekunde gelesen wird, müssen Sie die Taste mindestens eine Sekunde lang gedrückt halten, um sicherzustellen, dass das Ereignis erfasst wird.
gpio mode 0 in
while sleep 1; do
if [ "$(gpio read 0)" -eq 1 ]; then
reboot
fi
done &