我是 Gentoo 上的 Linux 新手。我正在尝试编写一条 udev 规则,该规则将在插入 USB 设备(特别是 USB 调制解调器)时运行 Python 脚本并传递一些信息。我有:
SUBSYSTEM == "usb", ACTION == "add", $ATTRS{vendor} = "?*", RUN += "/home/.../notify.py %k '$attr{vendor}'"
作为起点。
现在,notify.py 是一个可执行文件,试图帮助我调试,如下所示:
#!/usr/bin/python
import sys
log = open("log.txt", 'a')
for a in sys.argv:
log.write(a + "\n")
fi.close()
我不知道如何让“$attr{vendor}”通过;目前,只有 %k(设备内核)被传递和打印,以及我想添加的任何其他字符串参数。我浏览了整个互联网,尝试了“$attr{vendor}”(不输出任何内容)、“$attrs{vendor}”(输出“s{vendor}”)和“%s{vendor}”(不输出任何内容)。我尝试更改此规则的优先级,以防变量尚未定义或出现其他问题。我查看了其他规则文件,它们都无法完成我所做的事情,但它们确实设法使用了“$attr{[something]}”。
仍然令人困惑的是,如果我写类似的东西
GOTO+="$attr{vendor}"
vi 将其高亮显示为字符串,但是
RUN+="$attr{vendor}"
vi 会以不同的方式突出显示所有内容。我觉得这个错误与 RUN 的工作方式有关,或者与我对“$attr”的不正确使用有关,但我完全搞不懂。
这些帖子似乎做了一些与我尝试做的事情类似的事情。我很感激任何有关此问题的帮助或意见。
答案1
它有点复杂,因为规则是针对设备树中的每个节点进行评估的,并且某些信息在树的某些部分可用,但不能从树的另一部分引用。
最简单的方法是组合至少两条规则(如果您想过滤多个祖先,则可以扩展到更多规则)。
- 指定(正如您正确写的)一些具有您想要使用的必要信息的父设备(比如名称或特定于您的设备的 vendorId/productId),将任何需要的信息存储到环境变量中并为第二条规则升起一个标志,以便只能在该设备的后代上运行。
- 根据前一个标志(以及任何其他需要的属性)进行过滤并使用先前设置的环境变量(此时这些值通常不适用于该脚本)。
模拟代码,但展示了概念:
ACTION == "add", SUBSYSTEM == "usb", ATTRS{idProduct}=="0123", ATTRS{idVendor}=="4567" ENV{SEARCHED_DEVICE}="YES", ENV{VENDORID}="$attr{idVendor}", ENV{PRODUCTID}="$attr{idProduct}",
ACTION == "add", ENV{SEARCHED_DEVICE}=="YES", RUN+="/path/to/script.sh '$env{VENDORID}' '$env{PRODUCTID}'"
ENV{SEARCHED_DEVICE}
是用于指示匹配设备的标志ENV{VENDORID}
并ENV{PRODUCTID}
包含应保存到第二条规则的数据。'$env{VENDORID}' '$env{PRODUCTID}'
是对这些值的引用。
注意单等号(赋值)和双等号(测试值)。
答案2
希望有一天它能帮助到别人,我发现了两个帮助我解决问题的步骤。
首先是为了确保规则选择了要从中提取属性信息的父设备,因此我添加了一个
ATTRS{bDeviceClass} == "02"
将规则链接到所需的网络设备。
第二步,在第一步之后可能就没有必要了,就是设置一个环境变量并按如下方式调用它:
ENV{var} = ATTRS{bDeviceClass}, RUN+="/home/.../notify.py '$env{var}'"
这成功传递了变量。最后,似乎 $attr 和 %s 仍然不起作用。我被这个问题困扰了很久,现在我缺乏动力去尝试。