我在笔记本电脑上运行 Ubuntu 9.10(Karmic Koala),希望 NumLock 能够根据我的 USB 键盘是插入(numlock 开启)还是拔出(numlock 关闭)自动切换。
为了实现这一点,我首先安装了“numlockx”包,numlockx on
并且numlockx off
运行良好。
为了连接到设备系统,我想使用 udev。我读过“编写 udev 规则”,但我无法让 udev 规则正常工作。
首先,这里有一个输出示例dmesg
:
[20906.985102] usb 3-2:使用 uhci_hcd 和地址 6 的新低速 USB 设备 [20907.166403] usb 3-2:从 1 个选项中选择配置 #1 [20907.192904] 输入:Microsoft Natural® Ergonomic Keyboard 4000 作为 /devices/pci0000:00/0000:00:1a.0/usb3/3-2/3-2:1.0/input/input20 [20907.193100] microsoft 0003:045E:00DB.000B:input,hidraw1:USB HID v1.11 键盘 [Microsoft Natural® Ergonomic Keyboard 4000] 位于 usb-0000:00:1a.0-2/input0 上 [20907.217810] 输入:Microsoft Natural® Ergonomic Keyboard 4000 作为 /devices/pci0000:00/0000:00:1a.0/usb3/3-2/3-2:1.1/input/input21 [20907.217979] microsoft 0003:045E:00DB.000C:input,hidraw2:USB HID v1.11 设备 [Microsoft Natural® Ergonomic Keyboard 4000] 位于 usb-0000:00:1a.0-2/input1 上
我曾经udevadm info
收集过设备信息:
> udevadm 信息 -a -p /devices/pci0000:00/0000:00:1a.0/usb3/3-2/3-2:1.1/input/input21 查看设备'/devices/pci0000:00/0000:00:1a.0/usb3/3-2/3-2:1.1/input/input21': 内核==“输入21” 子系统==“输入” 司机==“” ATTR{phys}=="usb-0000:00:1a.0-2/input1" ATTR{uniq}=="" ATTR{modalias}=="输入:b0003v045Ep00DBe0111-e0,1,2,3,4,14,k71,72,73,74,75,77,79,7A,7B,7C,7D,7E,7F,80,81,82,83,84,85,86,87,88,89,8A,8B,8C,8E,90,96,98,9B,9C,9E,9F,A1,A3,A4,A5,A6,A7,A8,A9,AB,AC,AD,AE,B0,B1,B2,B3,B4,B5,B6,B8,B9,BA,BB,BC,BD ,BE,BF,C0,C1,C2,CE,CF,D0,D1,D2,D5,D9,DB,DF,E2,E7,E8,E9,EA,EB,F0,100,162,166,16A,16E,178,179,17A,17B,17C,17D,17F,180,181,182,185,18C,18D,192,193,195,1A0,1A1,1A2,1A3,1A4,1A5,1A6,1A7,1A8,1A9,1AA,1AB,1AC,1AD,1AE,1B0,1B1,1B7,r6,a20,m4,lsfw" 查看父设备'/devices/pci0000:00/0000:00:1a.0/usb3/3-2/3-2:1.1': 内核==“3-2:1.1” 子系统==“usb” 驱动程序==“usbhid” ATTRS{bInterfaceNumber}=="01" ATTRS{bAlternateSetting}==" 0" ATTRS{bNumEndpoints}=="01" ATTRS{bInterfaceClass}=="03" ATTRS{bInterfaceSubClass}=="00" ATTRS{bInterfaceProtocol}=="00" ATTRS{modalias}=="usb:v045Ep00DBd0173dc00dsc00dp00ic03isc00ip00" ATTRS{supports_autosuspend}=="1" 查看父设备'/devices/pci0000:00/0000:00:1a.0/usb3/3-2': 内核==“3-2” 子系统==“usb” 驱动程序==“usb” ATTRS{配置}=="" ATTRS{bNumInterfaces}==" 2" ATTRS{bConfigurationValue}=="1" ATTRS{bmAttributes}=="a0" ATTRS{bMaxPower}=="100mA" ATTRS{urbnum}=="532" ATTRS{idVendor}=="045e" ATTRS{idProduct}=="00db" ATTRS{bcdDevice}=="0173" ATTRS{bDeviceClass}=="00" ATTRS{bDeviceSubClass}=="00" ATTRS{bDeviceProtocol}=="00" ATTRS{bNumConfigurations}=="1" ATTRS{bMaxPacketSize0}=="8" ATTRS{速度}=="1.5" ATTRS{总线号}=="3" ATTRS{devnum}=="6" ATTRS{版本}==" 2.00" ATTRS{maxchild}=="0" ATTRS{quirks}=="0x0" ATTRS{授权}=="1" ATTRS{制造商}=="微软" 查看父设备'/devices/pci0000:00/0000:00:1a.0/usb3': 内核==“usb3” 子系统==“usb” 驱动程序==“usb” ATTRS{配置}=="" ATTRS{bNumInterfaces}==" 1" ATTRS{bConfigurationValue}=="1" ATTRS{bmAttributes}=="e0" ATTRS{bMaxPower}==" 0mA" ATTRS{urbnum}=="127" ATTRS{idVendor}=="1d6b" ATTRS{idProduct}=="0001" ATTRS{bcdDevice}=="0206" ATTRS{bDeviceClass}=="09" ATTRS{bDeviceSubClass}=="00" ATTRS{bDeviceProtocol}=="00" ATTRS{bNumConfigurations}=="1" ATTRS{bMaxPacketSize0}=="64" ATTRS{速度}=="12" ATTRS{总线号}=="3" ATTRS{devnum}=="1" ATTRS{版本}==" 1.10" ATTRS{maxchild}=="2" ATTRS{quirks}=="0x0" ATTRS{授权}=="1" ATTRS{制造商}=="Linux 2.6.31-16-通用 uhci_hcd" ATTRS{product}=="UHCI 主机控制器" ATTRS{序列号}=="0000:00:1a.0" ATTRS{authorized_default}=="1" 查看父设备'/devices/pci0000:00/0000:00:1a.0': 内核==“0000:00:1a.0” 子系统==“pci” 驱动程序==“uhci_hcd” ATTRS{供应商}=="0x8086" ATTRS{设备}=="0x2937" ATTRS{子系统供应商}=="0x1558" ATTRS{子系统设备}=="0x0860" ATTRS{class}=="0x0c0300" ATTRS{irq}=="16" ATTRS{local_cpus}=="ff" ATTRS{local_cpulist}=="0-7" ATTRS{modalias}=="pci:v00008086d00002937sv00001558sd00000860bc0Csc03i00" ATTRS{broken_parity_status}=="0" ATTRS{msi_bus}=="" 查看父设备'/devices/pci0000:00': 内核==“pci0000:00” 子系统=="" 司机==“”
因此我创建了一个名为的文件/etc/udev/rules.d/usb-keyboard.rules
:
# 插入键盘时打开 NumLock。 ACTION=="添加", ATTRS{制造商}=="Microsoft", SUBSYSTEM=="输入", RUN+="/usr/bin/numlockx on" # 拔下键盘时关闭 NumLock。 ACTION=="删除", ATTRS{制造商}=="Microsoft", SUBSYSTEM=="输入", RUN+="/usr/bin/numlockx off"
我已经用来udevadm test
验证规则是否正确:
> udevadm 测试 --action=add /devices/pci0000:00/0000:00:1a.0/usb3/3-2/3-2:1.1/input/input21 run_command:调用:测试 udevadm_test:版本 147 [...] parse_file:读取‘/etc/udev/rules.d/usb-keyboard.rules’作为规则文件 udev_rules_new:规则使用 180864 字节标记(15072 * 12 字节),31614 字节缓冲区 udev_rules_new:临时索引已使用 49760 字节(2488 * 20 字节) udev_device_new_from_syspath:设备 0x28d7d80 具有 devpath '/devices/pci0000:00/0000:00:1a.0/usb3/3-2/3-2:1.1/input/input21' udev_rules_apply_to_event:运行'/sbin/modprobe -b $env{MODALIAS}'/lib/udev/rules.d/80-drivers.rules:5 udev_rules_apply_to_event:运行'socket:@/org/freedesktop/hal/udev_event'/lib/udev/rules.d/90-hal.rules:2 udev_device_new_from_syspath:设备 0x28d8560 具有 devpath '/devices/pci0000:00/0000:00:1a.0/usb3/3-2/3-2:1.1' udev_device_new_from_syspath:设备 0x28d8708 具有 devpath '/devices/pci0000:00/0000:00:1a.0/usb3/3-2' udev_rules_apply_to_event:运行‘/usr/bin/numlockx on’/etc/udev/rules.d/usb-keyboard.rules:7 udevadm_test:UDEV_LOG=6 udevadm_test:DEVPATH=/设备/pci0000:00/0000:00:1a.0/usb3/3-2/3-2:1.1/输入/输入21 udevadm_test:产品=3/45e/db/111 udevadm_test:NAME="Microsoft Natural® 人体工学键盘 4000" udevadm_test:PHYS="usb-0000:00:1a.0-2/input1" udevadm_test:UNIQ=”” udevadm_test:EV==10001f udevadm_test:密钥==837fff 2c3027 bf004444 0 0 1 10f84 8a27c007 ff7f7bfa d9415fff febeffdf ffefffff ffffffff fffffffe udevadm_test:REL==40 udevadm_测试:ABS==1 0 udevadm_test:MSC==10 udevadm_test:MODALIAS=输入:b0003v045Ep00DBe0111-e0,1,2,3,4,14,k71,72,73,74,75,77,79,7A,7B,7C,7D,7E,7F,80,81, 82,83,84,85,86,87,88,89,8A,8B,8C,8E,90,96,98,9B,9C,9E,9F,A1,A3,A4,A5,A6,A7, A8,A9,AB,AC,AD,AE,B0,B1,B2,B3,B4,B5,B6,B8,B9,BA,BB,BC,BD,BE ,BF,C0,C1,C2,CE,CF,D0,D1,D2,D5,D9,DB,DF,E2,E7,E8,E9,EA,EB,F0,100,162,166,16A,16E,178,179,17A ,17B,17C,17D,17F,180,181,182,185,18C,18D,192,193,195,1A0,1A1,1A2,1A3,1A4,1A5,1A6,1A7,1A8,1A9,1AA,1AB,1AC,1AD,1AE,1B0,1B1 ,1B7,r6,a20,m4,lsfw udevadm_test:ACTION=添加 udevadm_test:子系统=输入 udevadm_test:运行:'/sbin/modprobe -b 输入:b0003v045Ep00DBe0111-e0,1,2,3,4,14,k71,72,73,74,75,77,79,7A,7B,7C,7D,7E ,7F,80,81,82,83,84,85,86,87,88,89,8A,8B,8C,8E,90,96,98,9B,9C,9E,9F,A1,A3,A4 ,A5,A6,A7,A8,A9,AB,AC,AD,AE,B0,B1,B2,B3,B4,B5,B6,B8,B9,BA,BB,BC,BD,BE,BF,C 0,C1,C2,CE,CF,D0,D1,D2,D5,D9,DB,DF,E2,E7,E8,E9,EA,EB,F0,100,162,166,16A,16E,178,179,17A,17B, 17C,17D,17F,180,181,182,185,18C,18D,192,193,195,1A0,1A1,1A2,1A3,1A4,1A5,1A6,1A7,1A8,1A9,1AA,1AB,1AC,1AD,1AE,1B0,1B1,1B7, r6,a20,m4,lsfw' udevadm_test:运行:'socket:@/org/freedesktop/hal/udev_event' udevadm_test:运行:'/usr/bin/numlockx on'
这是“删除”测试:
> udevadm 测试 --action=删除 /devices/pci0000:00/0000:00:1a.0/usb3/3-2/3-2:1.1/input/input21 run_command:调用:测试 udevadm_test:版本 147 [...] parse_file:读取‘/etc/udev/rules.d/usb-keyboard.rules’作为规则文件 udev_rules_new:规则使用 180864 字节标记(15072 * 12 字节),31614 字节缓冲区 udev_rules_new:临时索引已使用 49760 字节(2488 * 20 字节) udev_device_new_from_syspath:设备 0xd2fd80 具有设备路径“/devices/pci0000:00/0000:00:1a.0/usb3/3-2/3-2:1.1/input/input21” udev_rules_apply_to_event:运行'socket:@/org/freedesktop/hal/udev_event'/lib/udev/rules.d/90-hal.rules:2 udev_device_new_from_syspath:设备 0xd2fff8 具有设备路径“/devices/pci0000:00/0000:00:1a.0/usb3/3-2/3-2:1.1” udev_device_new_from_syspath:设备 0xd30690 具有设备路径“/devices/pci0000:00/0000:00:1a.0/usb3/3-2” udev_rules_apply_to_event:运行‘/usr/bin/numlockx off’/etc/udev/rules.d/usb-keyboard.rules:10 udevadm_test:UDEV_LOG=6 udevadm_test:DEVPATH=/设备/pci0000:00/0000:00:1a.0/usb3/3-2/3-2:1.1/输入/输入21 udevadm_test:产品=3/45e/db/111 udevadm_test:NAME="Microsoft Natural® 人体工学键盘 4000" udevadm_test:PHYS="usb-0000:00:1a.0-2/input1" udevadm_test:UNIQ=”” udevadm_test:EV==10001f udevadm_test:密钥==837fff 2c3027 bf004444 0 0 1 10f84 8a27c007 ff7f7bfa d9415fff febeffdf ffefffff ffffffff fffffffe udevadm_test:REL==40 udevadm_测试:ABS==1 0 udevadm_test:MSC==10 udevadm_test:MODALIAS=输入:b0003v045Ep00DBe0111-e0,1,2,3,4,14,k71,72,73,74,75,77,79,7A,7B,7C,7D,7E,7F,80,81, 82,83,84,85,86,87,88,89,8A,8B,8C,8E,90,96,98,9B,9C,9E,9F,A1,A3,A4,A5,A6,A7, A8,A9,AB,AC,AD,AE,B0,B1,B2,B3,B4,B5,B6,B8,B9,BA,BB,BC,BD,BE ,BF,C0,C1,C2,CE,CF,D0,D1,D2,D5,D9,DB,DF,E2,E7,E8,E9,EA,EB,F0,100,162,166,16A,16E,178,179,17A ,17B,17C,17D,17F,180,181,182,185,18C,18D,192,193,195,1A0,1A1,1A2,1A3,1A4,1A5,1A6,1A7,1A8,1A9,1AA,1AB,1AC,1AD,1AE,1B0,1B1 ,1B7,r6,a20,m4,lsfw udevadm_test:ACTION=删除 udevadm_test:子系统=输入 udevadm_test:运行:'socket:@/org/freedesktop/hal/udev_event' udevadm_test:运行:'/usr/bin/numlockx off'
问题是,当键盘插入或拔出时,NumLock 状态不会改变。我尝试重新启动 udev 服务,但没有成功。我的 udev 规则错了吗?我是不是用错了方法?
答案1
问题是您可能已经在(正如其名称所暗示的)某些 X 环境中测试过 numlockx。X 客户端(连接到 X 服务器的 GUI 程序,例如 Firefox 或 GEdit)需要知道要连接的服务器,还必须通过某种授权。尝试从普通控制台登录,无论是 root 还是普通用户,然后启动一些 GUI 应用程序:它会显示一些与 DISPLAY 相关的错误,因为它不知道。
要修复此问题,您需要设置环境变量 DISPLAY;如果您只有一个 X 服务器,则它几乎总是具有地址:0。
在普通控制台上尝试一下:输入numlockx on
,它会显示“打开显示错误!”。输入DISPLAY=:0 numlockx on
,它就会起作用(至少对我来说是有效的)。
因此您可以在 udev 中设置此环境变量或者直接启动sh -c 'DISPLAY=:0 numlockx <state>'
。
答案2
这两个命令可以用来调试很多 udev 问题:
udevd --debug-trace --verbose
strace -p pid_of_udevd -f -e trace=open,exec
请注意,args 在不同版本上可能会发生变化...
答案3
这可能纯属巧合,但当我以数字开头命名它时,我的 udev 规则就开始起作用,例如80-usb-keyboard.rules
。