是否可以用 udev 规则仅覆盖 UDEV 事件?

是否可以用 udev 规则仅覆盖 UDEV 事件?

当我查看 USB 设备的输出时udevadm monitor,有KERNELUDEV事件。

我只能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

相关内容