Fad*_*ass 9 bash shell-script raspberry-pi
我创建了一个迷你脚本,只需按一下按钮即可重新启动我的 Raspberry Pi。该脚本简单地使用wiringPi(gpio命令)将引脚0(Raspberry Pi标准编号顺序中的引脚17)设置为输入,然后读取该值直到为1(即按下或按住按钮时)。
这是我的脚本:
gpio mode 0 in
while (true)
do
if [ `gpio read 0` -eq 1 ]
then
echo password | sudo -S reboot
break
fi
done &
Run Code Online (Sandbox Code Playgroud)
该脚本工作正常,一切正常。
然而,对于那些不熟悉 Pi 的人来说,它带有非常有限的硬件资源(包括 512 MB 的内存),很容易被我正在使用的循环消耗掉。
我在这里试图实现的是为 bash 找到另一种方法来找出值何时从0
变为 ,1
而不必为它专门提供一个更像是无条件循环的方法。这是可行的吗?请分享您的想法。
Gil*_*il' 12
该脚本是一个繁忙的循环:它一遍又一遍地读取 GPIO 引脚。它不会消耗太多内存,但会使 CPU 保持忙碌。
您应该将 GPIO 引脚设置为边缘模式。该gpio
实用程序有一个wfi
(等待中断)命令,您可以使用该命令对边沿触发做出反应。(gpio wfi
提出问题时不存在。)
set -e
gpio mode 0 in
gpio wfi 0 rising
echo password | sudo -S reboot
Run Code Online (Sandbox Code Playgroud)
有一个用于 GPIO 访问的Python 库,它支持边缘模式。这是一些完全未经测试的 Python 代码,它们应该可以满足您的需求。
#!/usr/bin/env python
import os
from RPi import GPIO
GPIO.wait_for_edge(0, GPIO.RISING)
system("sudo reboot")
Run Code Online (Sandbox Code Playgroud)
(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 ""
Run Code Online (Sandbox Code Playgroud)
请注意,如果 sudoers 文件中有同一个用户需要密码的NOPASSWD
条目,则该条目必须在后面。
一旦触发重新启动,您无需中断循环,系统无论如何都会停止。
如果您决定继续使用这个 shell 脚本,并且您的版本gpio
太旧而无法使用wfi
子命令,这里有一个改进的版本,它每秒只检查一次按钮状态。请注意,由于引脚每秒仅读取一次,这意味着您需要按住按钮至少一秒钟以确保事件被拾取。
gpio mode 0 in
while sleep 1; do
if [ "$(gpio read 0)" -eq 1 ]; then
reboot
fi
done &
Run Code Online (Sandbox Code Playgroud)