使用此脚本在您的网络上查找 Raspberry Pi

使用脚本触发 LED 闪烁,识别集群中的特定 Raspberry Pi。
149 位读者喜欢此文。
Raspberries with pi symbol overlay

Dwight Sipler on Flickr

我们都经历过。“我要买一个 Raspberry Pi 试试。看起来挺酷的。” 然后,就像《星际迷航》里的毛球一样,突然之间你就有了 Kubernetes 集群NFS 服务器Tor 代理。 甚至可能是一个 酒店预订系统

Pi 们占据了桌面。 它们蔓延到地板上。 安装在午餐盒中的 Raspberry Pi 计算模块的载板堆满了架子。

……或者这只是我?

我敢打赌,如果你有一个 Raspberry Pi,你 *至少* 有两个其他的,而且该死的是,它们看起来都一样。

这就是我最近发现自己所处的情况,当时我正在测试我在其中一个 Raspberry Pi 上设置的网络文件系统 (NFS) 服务器。 我需要插入一个 USB 硬盘,但是……插到哪个呢? 老 Lingonberry Pi 是选定的主机,我通过 SSH 连接到它,但它实际上是哪个 *物理* RPi 呢? 没有办法知道……

还是有办法?

Raspberry Pis stacked up in cluster cases

这么多 Raspberry Pi。 哪个是 Lingonberry? (Chris Collins, CC BY-SA 4.0)

在之前的一份工作中,我有时会在我们的数据中心处理服务器,其中一些服务器有一个很棒的功能:服务器前面有一个 ID 按钮,按下该按钮会启动服务器正面和背面的 LED 闪烁。 如果我需要处理服务器的另一侧,我可以按下 ID 按钮,然后 *一路* 走到机架的另一侧,轻松找到正确的服务器。

我需要类似的东西来找到 Lingonberry。

Pi 上没有任何按钮,但是有 LED,在快速 Google 搜索后,我了解到 其中一个是可以控制的响起疯狂的笑声。

有三个重要的信息要知道。 首先,LED 路径:在 Raspberry Pi 上,至少是那些运行 Ubuntu 20.04 的,前面的(用户可控制的)LED 位于 /sys/class/leds/led0。 如果您导航到它,您会发现它是一个指向目录的符号链接,该目录中有许多文件。 两个重要的文件是 triggerbrightness

trigger 文件控制什么点亮 LED。 如果你 cat 该文件,你会发现一个列表

none usb-gadget usb-host rc-feedback rfkill-any 
rfkill-none kbd-scrolllock kbd-numlock kbd-capslock 
kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock 
kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock
kbd-ctrlrlock timer oneshot disk-activity disk-read
disk-write ide-disk mtd nand-disk heartbeat backlight
gpio cpu cpu0 cpu1 cpu2 cpu3 default-on input panic
mmc1 [mmc0] bluetooth-power rfkill0 
unimac-mdio--19:01:link unimac-mdio--19:01:1Gbps 
unimac-mdio--19:01:100Mbps unimac-mdio--19:01:10Mbps

方括号中的项目表示触发 LED 的内容; 在上面的示例中,它是 [mmc0]——插入 Raspberry Pi 的 SD 卡的磁盘活动。 但是,trigger 文件不是普通文件。 您不是直接编辑它,而是通过将其中一个触发器回显到文件中来更改触发器。

为了识别 Lingonberry,我需要暂时禁用 [mmc0] 触发器,这样我就可以按照 *我* 想要的方式让 LED 工作。 在脚本中,我通过将 "none" 回显到 trigger 文件中来禁用所有触发器

# You must be root to do this
$ echo none >trigger

$ cat trigger
[none] usb-gadget usb-host rc-feedback rfkill-any rfkill-none kbd-scrolllock kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock timer oneshot disk-activity disk-read disk-write ide-disk mtd nand-disk heartbeat backlight gpio cpu cpu0 cpu1 cpu2 cpu3 default-on input panic mmc1 mmc0 bluetooth-power rfkill0 unimac-mdio--19:01:link unimac-mdio--19:01:1Gbps unimac-mdio--19:01:100Mbps unimac-mdio--19:01:10Mbps

在上面 trigger 文件的内容中,您可以看到 [none] 现在是选定的触发器。 现在 LED 关闭并且不闪烁。

接下来是 brightness 文件。 您可以通过将 0 或 1 回显到文件中来控制 LED 是亮 (1) 还是灭 (0)。 交替使用 1 和 0 会使 LED 闪烁,并且在中间进行一秒钟的睡眠会产生规则的开/关闪烁,这与原本会触发 LED 的任何活动都不同。 这非常适合识别 Raspberry Pi。

最后,如果您没有将 trigger 文件设置回触发器,它将保持关闭状态。 大多数时候这不是你想要的——最好看到磁盘活动。 这意味着您必须确保您编写的任何脚本都会在完成或中断时重置触发器。 这需要一个 信号陷阱。 陷阱将捕获 SIGINTSIGTERM(或其他)信号,并在退出前执行一些代码。 这样,如果脚本被中断——比如您按下 CTRL+C 停止它——它仍然可以重置触发器。

有了这些新知识,我能够快速编写一个脚本(在 MIT 许可证 下可用)并将其放在我的 Raspberry Pi 上

#!/bin/bash

set -o errexit
set -o nounset

trap quit INT TERM

COUNT=0

if ! [ $(id -u) = 0 ]; then
   echo "Must be run as root."
   exit 1
fi

LED="/sys/class/leds/led0"

if [[ ! -d $LED ]]
then
  echo "Could not find an LED at ${LED}"
  echo "Perhaps try '/sys/class/leds/ACT'?"
  exit 1
fi

function quit() {
  echo mmc0 >"${LED}/trigger"
}

echo -n "Blinking Raspberry Pi's LED - press CTRL-C to quit"

echo none >"${LED}/trigger"

while true
do
  let "COUNT=COUNT+1"
  if [[ $COUNT -lt 30 ]]
  then
    echo 1 >"${LED}/brightness"
    sleep 1
    echo 0 >"${LED}/brightness"
    sleep 1
  else
    quit
    break
  fi
done

此脚本检查 LED 控制目录是否存在,禁用 [mmc0] 触发器,然后启动一个循环,每秒闪烁一次 LED。 它还包括一个陷阱来捕获 INTTERM 信号并重置触发器。 我将此脚本复制到我的所有 Raspberry Pi 上,并且每当需要识别其中一个时,我只需运行它。 它完美地识别了老 Lingonberry,所以我可以为 NFS 服务器设置磁盘,并且从那时起我已经使用了它很多次。

需要注意的一件事是,LED 的路径在其他发行版中可能有所不同。 /sys/class/leds 目录中还有其他 LED,但用户无法控制它们; 它们被连接到 Raspberry Pi 固件的不同部分。

你有什么酷炫的 Raspberry Pi 技巧吗? 请在评论中告诉我! 我一直对学习其他人如何处理他们的 Pi 感染很感兴趣!

接下来要读什么
Chris Collins
Chris Collins 是 Red Hat 的 SRE 和 OpenSource.com 的通讯员,他对自动化、容器编排及其周围的生态系统充满热情,并且喜欢为了乐趣在家中重新创建企业级技术。

4 条评论

不错的脚本! 我有 10 个(左右),将会使用它。

嗨,喜欢这个脚本,但我无法让它在 Raspberry Pi OS 上工作。 我在第 17 行和第 24 行收到错误...不确定我做错了什么,但我直接从网页复制并粘贴了脚本。

这是错误
./blink.sh: 17: ./blink.sh: [[: 未找到
./blink.sh: 24: ./blink.sh: 语法错误: "(" 意外

由于我不太擅长脚本编写,所以可能是一些愚蠢的事情。 请不要犹豫指出。 ;-)

谢谢
P.

"[[" 是 Bash 构造,脚本尝试使用旧的 Bourse shell ("/bin/sh") 运行。

将脚本的第一行更改为
#!/bin/bash

回复 Pierre Rochefort (未验证)

谢谢 Simon,我在写这篇文章时是从我自己的测试脚本中复制和粘贴的,并且一定错过了这一点! 我会更新这篇文章的。

回复 Simon Reap (未验证)

Creative Commons License本作品根据 Creative Commons Attribution-Share Alike 4.0 International License 许可。
© . All rights reserved.