![是否可以用 udev 规则仅覆盖 UDEV 事件?](https://linux22.com/image/1613494/%E6%98%AF%E5%90%A6%E5%8F%AF%E4%BB%A5%E7%94%A8%20udev%20%E8%A7%84%E5%88%99%E4%BB%85%E8%A6%86%E7%9B%96%20UDEV%20%E4%BA%8B%E4%BB%B6%EF%BC%9F.png)
当我查看 USB 设备的输出时udevadm monitor
,有KERNEL
和UDEV
事件。
我只能UDEV
用 udev 规则来处理事件吗?
$ udevadm monitor | grep "mouse"
KERNEL[122.593013] add /devices/pci0000:00/0000:00:14.0/usb3/3-7/3-7:1.0/0003:1234:5678:0006/input/input12/mouse1 (input)
UDEV [123.643263] add /devices/pci0000:00/0000:00:14.0/usb3/3-7/3-7:1.0/0003:1234:5678:0006/input/input12/mouse1 (input)
我试过了:
ACTION=="add" \
, SUBSYSTEM=="input" \
, UDEV=="mouse*" \
, ATTRS{idVendor}=="1234" \
, ATTRS{idProduct}=="5678" \
, RUN+="/usr/local/bin/do_something.sh"
我正在使用 Ubuntu 18.04(核心: 4.15.0-72-generic
)。
答案1
否,因为 udev 事件是发出的因此规则处理。
(这就是 udev 首先复制这些事件的原因:它们是在规则处理完成后发送出去的,并且它们包含规则可能添加的所有额外信息。)
如果你想确保规则不会重复执行:这已经不会发生了。规则是仅有的由“内核”事件触发。
如果您需要访问另一条规则添加的信息:请确保您的自定义 .rules 文件的文件名排在您需要的文件名之后。例如,如果 70-foo.rules 设置了必要的属性,请将您的属性放入 71-whatever.rules 或 80-meh.rules 中。
如果您想运行与 X11 相关的命令,例如“xinput”或“xmodmap”:不要。真的不要。除非您的 CPU 可以穿越时空,否则它不会起作用。看看是否可以通过 /etc/X11/Xorg.conf 实现相同的设置。
(或者,编写一个挂钩 X11 事件的工具 - 示例见下面。)
依恋:x11-device-monitor.c
#if 0
src = $(MAKEFILE_LIST)
app = $(basename $(src))
$(app): LDLIBS = -lX11 -lXi
$(app): $(src)
define source
#endif
/* (c) 2018 Mantas Mikulėnas <[email protected]> */
/* Released under the MIT license <https://spdx.org/licenses/MIT> */
/* http://who-t.blogspot.com/2009/05/xi2-recipes-part-1.html */
#define _GNU_SOURCE
#include <X11/Xlib.h>
#include <X11/extensions/XInput2.h>
#include <err.h>
#include <stdlib.h>
int main(void) {
Display *d;
Window rw;
int xinput_op, foo;
unsigned char mask[2] = {0};
XIEventMask ximask;
XEvent ev;
XIHierarchyEvent *hev;
d = XOpenDisplay(NULL);
if (!d)
errx(1, "cannot open display");
if (!XQueryExtension(d, "XInputExtension", &xinput_op, &foo, &foo))
errx(1, "no XInput extension on display");
rw = RootWindow(d, DefaultScreen(d));
XISetMask(mask, XI_HierarchyChanged);
ximask.mask = mask;
ximask.mask_len = sizeof(mask);
ximask.deviceid = XIAllDevices;
XISelectEvents(d, rw, &ximask, 1);
XFlush(d);
for (;;) {
XNextEvent(d, &ev);
if (ev.type != GenericEvent)
continue;
/* XInput2 always uses extended events */
/* http://who-t.blogspot.com/2009/07/xi2-and-xlib-cookies.html */
if (ev.xcookie.extension != xinput_op)
continue;
if (ev.xcookie.evtype != XI_HierarchyChanged)
continue;
if (!XGetEventData(d, &ev.xcookie))
continue;
hev = ev.xcookie.data;
if (!(hev->flags & XIDeviceEnabled))
continue;
warnx("device enabled");
system("xmodmap ~/.Xmodmap");
XFreeEventData(d, &ev.xcookie);
}
}
#if 0
endef
#endif