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

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

Dwight Sipler 在 Flickr 上

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

Pi 们占满了桌面。它们蔓延到地板上。安装在饭盒里的 Raspberry Pi 计算模块载板散落在架子上。

……或者也许只是我?

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

最近我在测试一个在我的 Raspberry Pi 上设置的网络文件系统 (NFS) 服务器时,发现自己处于这种情况。我需要插入一个 USB 硬盘驱动器,但是……插到哪个上? 老凌戈莓派是选定的主机,我通过 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 是可控的开始疯狂大笑。

有三个重要的部分需要了解。首先,LED 路径:在 Raspberry Pi 上,至少在运行 Ubuntu 20.04 的 Raspberry Pi 上,前面(和用户可控的)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”回显到触发器文件中来禁用所有触发器

# 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 上,并且每次我需要识别其中一个时,我只需运行它。 它可以完美地识别 Ol' 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本作品采用知识共享署名 - 相同方式共享 4.0 国际许可协议授权。
© . All rights reserved.