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

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

Dwight Sipler 来自 Flickr

我们都经历过。“我要买一个 Raspberry Pi 来试试。它们看起来有点酷。” 然后,就像企业号上的小毛球一样,突然间你就有了 Kubernetes 集群NFS 服务器Tor 代理。甚至可能还有一个 酒店预订系统

树莓派堆满了桌子。它们溢出到地板上。安装在午餐盒中的 Raspberry Pi 计算模块的载板散落在架子上。

……或者也许只是我?

我敢打赌,如果你有一个 Raspberry Pi,你至少还有另外两个,而且天哪,它们看起来都一样。

这就是我最近遇到的情况,当时我正在测试我在我的一个 Raspberry Pi 上设置的网络文件系统 (NFS) 服务器。我需要插入一个 USB 硬盘,但是……插到哪个?“老蔓越莓派”是选定的主机,我通过 SSH 连接到它,但它到底是哪个物理 RPi?我根本无从知晓……

还是有办法?

Raspberry Pis stacked up in cluster cases

这么多 Raspberry Pi。哪个是蔓越莓?(Chris Collins,CC BY-SA 4.0

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

我需要类似的东西来找到“蔓越莓”。

树莓派上没有任何按钮,但有 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 文件不是普通文件。与其直接编辑它,不如通过将其中一个触发器回显到文件中来更改触发器。

为了识别“蔓越莓”,我需要暂时禁用 [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 上,每当我需要识别其中一个时,我只需运行它。它完美地识别出了“老蔓越莓”,所以我可以为 NFS 服务器设置磁盘,并且从那时起我已经使用过多次。

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

您有什么很酷的 Raspberry 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 (未验证) 的评论

知识共享许可协议本作品根据知识共享署名-相同方式共享 4.0 国际许可协议获得许可。
© . All rights reserved.