Phân tích và giải pháp hiện đại
Kịch bản là một vòng lặp bận rộn: nó cứ đọc đi lặp lại các chân GPIO. Nó không tiêu tốn nhiều bộ nhớ nhưng nó khiến CPU bận rộn.
Bạn nên đặt chân GPIO ở chế độ cạnh. Các gpio
tiện ích có wfi
(chờ ngắt) lệnh mà bạn có thể sử dụng để phản ứng với một kích hoạt cạnh. ( gpio wfi
không tồn tại trở lại khi câu hỏi được hỏi.)
set -e
gpio mode 0 in
gpio wfi 0 rising
echo password | sudo -S reboot
Một giải pháp Python
Có một thư viện Python để truy cập GPIO , hỗ trợ chế độ cạnh. Đây là một số mã Python hoàn toàn chưa được kiểm tra sẽ làm những gì bạn muốn.
#!/usr/bin/env python
import os
from RPi import GPIO
GPIO.wait_for_edge(0, GPIO.RISING)
system("sudo reboot")
Mẹo bổ sung vỏ
(true)
có thể được viết chỉ true
. Các dấu ngoặc đơn tạo ra một quy trình con, điều này là hoàn toàn không cần thiết.
`gpio read 0`
nên trong dấu ngoặc kép. Không có dấu ngoặc kép, đầu ra của lệnh được coi là một danh sách các mẫu ký tự đại diện tên tệp. Với dấu ngoặc kép, đầu ra của lệnh được coi là một chuỗi. Luôn đặt dấu ngoặc kép quanh thay thế lệnh và thay thế biến: "$(some_command)"
, "$some_variable"
. Ngoài ra, bạn nên sử dụng cú pháp $(…)
chứ không phải `…`
: nó có cùng một nghĩa chính xác, nhưng cú pháp backquote có một số quirks phân tích khi lệnh phức tạp. Như vậy:if [ "$(gpio read 0)" -eq 1 ]
Đừng đặt mật khẩu gốc trong tập lệnh. Nếu tập lệnh đang chạy bằng root, bạn hoàn toàn không cần sudo. Nếu tập lệnh không chạy dưới quyền root, thì hãy cho phép người dùng chạy tập lệnh để chạy sudo reboot
mà không cần cung cấp mật khẩu. Chạy visudo
và thêm dòng sau:
userwhorunsthescript ALL = (root) NOPASSWD: /sbin/reboot ""
Lưu ý rằng nếu có một mục nhập cho cùng một người dùng trong tệp sudoers yêu cầu mật khẩu, NOPASSWD
mục nhập đó phải xuất hiện sau.
Khi bạn kích hoạt khởi động lại, bạn không cần phải phá vỡ vòng lặp, hệ thống sẽ dừng lại.
Nếu bạn quyết định tiếp tục sử dụng tập lệnh shell này và phiên bản của bạn gpio
quá cũ để có wfi
tiểu ban, thì đây là phiên bản cải tiến chỉ kiểm tra trạng thái nút mỗi giây. Lưu ý rằng vì pin chỉ được đọc một lần mỗi giây, điều này có nghĩa là bạn cần giữ nút này trong ít nhất một giây để chắc chắn rằng sự kiện đã được chọn.
gpio mode 0 in
while sleep 1; do
if [ "$(gpio read 0)" -eq 1 ]; then
reboot
fi
done &