首页 > 解决方案 > 从 udev 规则中调用变量

问题描述

我有多个 udev 规则来检查是否 ATTRS{name}=="abc123" 并在该设备存在时调用各种函数。这些 udev 规则位于多个位置,因为这是在 bitbake 中为自定义嵌入式操作系统创建的。现在,如果我想更改此设备以测试不同的硬件,每次更改每个 ATTR{name} 调用都太耗时了。

我的解决方案是在某个 conf 文件(待确定)中定义一个 var,例如 $UDEVVAR="[device_name]",然后将每个 ATTR{name} 调用更改为 ATTR{name}=="${UDEVVAR }”。

我已经在为概念证明编写的本地规则中测试了这种方法,尽管该规则没有调用。这个地方规则有点不同,虽然遵循相同的概念。无论我放在哪里的闪存驱动器都没有定义 ATTR{name},所以我使用了 USB 鼠标和那个闪存驱动器。这个 udev 规则是:

SUBSYSTEM=="${UDEVVAR}", ACTION=="add", RUN+="/usr/local/bin/trigger.sh"

trigger.sh 只是将日期时间戳写入日志文件。当将 SUBSYSTEM 硬编码为 =="block" 时,规则调用成功,但在定义 UDEVVAR="block" 时,规则不会被调用。这个想法是,如果可行,那么我将定义 UDEVVAR="hidraw" 来测试鼠标。

我似乎找不到太多关于任何人试图做这样的事情的文档。我想我犯了某种语法错误,或者 udev 规则可能不允许这样的事情。

我很感激任何帮助!

标签: linuxembedded-linuxbitbakeudev

解决方案


您应该能够在 udev 规则中使用 ENV。

SUBSYSTEM=="$env{UDEV_SUBSYS}", ACTION=="add", RUN+="/usr/local/bin/trigger.sh"

甚至将其用作过滤条件(以便有条件地运行 N 个相似的给定规则):

ENV{UDEV_SUBSYS}=="hidraw", ACTION=="add", RUN+="/usr/local/bin/trigger.sh"

然后您必须及时定义变量,例如/etc/environment(甚至使用u-bootsetenv):

UDEV_SUBSYS="hidraw"

如果您希望在启动完成后(即从用户进程)动态更改它,这还不够;您将必须实施一种机制,在更新环境后将udev作为其子项重新启动。

有关详细信息,请参阅udev 手册

注意:这和手册一样适用于systemd-udevd. YMMV 与其他udev口味。

编辑:/etc/environment不太支持busybox init。请查看/etc/inittab您可能拥有的任何初始化脚本,并在那里获取环境文件(或设置/导出变量)。

编辑 2:可悲的是,似乎只有NAME, SYMLINK, PROGRAM, OWNER, GROUP, MODE, SECLABEL, 和RUN字段支持替换。:( 我之前在手册中忽略了这一点。

您可能会在编写一个接收设备数据作为环境并在PROGRAM现场提供该数据以进行匹配的 shell 脚本方面取得一些成功。如果认为匹配,则返回 0。


推荐阅读