Analisis dan solusi modern
Script adalah loop sibuk: ia terus membaca pin GPIO berulang kali. Tidak memakan banyak memori tetapi membuat CPU sibuk.
Anda harus mengatur pin GPIO dalam mode tepi. The gpio
utilitas memiliki wfi
(menunggu interrupt) perintah yang dapat Anda gunakan untuk bereaksi terhadap pemicu tepi. ( gpio wfi
Tidak ada kembali ketika pertanyaan diajukan.)
set -e
gpio mode 0 in
gpio wfi 0 rising
echo password | sudo -S reboot
Solusi Python
Ada perpustakaan Python untuk akses GPIO , yang mendukung mode tepi. Berikut adalah beberapa kode Python yang belum teruji yang harus melakukan apa yang Anda inginkan.
#!/usr/bin/env python
import os
from RPi import GPIO
GPIO.wait_for_edge(0, GPIO.RISING)
system("sudo reboot")
Kiat shell tambahan
(true)
bisa dituliskan saja true
. Kurung membuat subproses, yang sama sekali tidak perlu.
`gpio read 0`
harus dalam tanda kutip ganda. Tanpa tanda kutip, output perintah diperlakukan sebagai daftar pola wildcard nama file. Dengan tanda kutip ganda, output dari perintah diperlakukan sebagai string. Selalu beri tanda kutip ganda di sekitar pergantian perintah dan pergantian variabel: "$(some_command)"
, "$some_variable"
. Juga, Anda harus menggunakan sintaks $(…)
daripada `…`
: itu memiliki arti yang persis sama, tetapi sintaks backquote memiliki beberapa kebiasaan parsing ketika perintah kompleks. Jadi:if [ "$(gpio read 0)" -eq 1 ]
Jangan letakkan kata sandi root di skrip. Jika skrip berjalan sebagai root, Anda tidak perlu sudo sama sekali. Jika skrip tidak berjalan sebagai root, maka beri pengguna izin menjalankan skrip sudo reboot
tanpa memberikan kata sandi. Jalankan visudo
dan tambahkan baris berikut:
userwhorunsthescript ALL = (root) NOPASSWD: /sbin/reboot ""
Perhatikan bahwa jika ada entri untuk pengguna yang sama dalam file sudoers yang memerlukan kata sandi, NOPASSWD
entri tersebut harus muncul setelah itu.
Setelah Anda memicu reboot, Anda tidak perlu memutus loop, sistem akan tetap berhenti.
Jika Anda memutuskan untuk tetap menggunakan skrip shell ini, dan versi Anda gpio
terlalu tua untuk memiliki wfi
sub- perintah , inilah versi yang disempurnakan yang hanya memeriksa status tombol setiap detik. Perhatikan bahwa karena pin hanya dibaca sekali per detik, ini berarti Anda harus terus menekan tombol setidaknya selama satu detik untuk memastikan bahwa acara tersebut diambil.
gpio mode 0 in
while sleep 1; do
if [ "$(gpio read 0)" -eq 1 ]; then
reboot
fi
done &