udev 规则用于在插入 USB 键盘时自动加载键盘布局

udev 规则用于在插入 USB 键盘时自动加载键盘布局

当我插入 USB 键盘时,我尝试加载新的键盘布局,但我的 udev 规则不起作用。

SUBSYSTEM=="输入", ATTR{idVendor}=="062a", ATTR{idProduct}=="0201", GOTO="usb_xmodmap_auto"

标签="usb_xmodmap_auto"
ACTION=="添加", RUN+="/usr/bin/xmodmap ~/.usbXmodmap"
ACTION=="删除", RUN+="/usr/bin/xmodmap ~/.pndXmodmap"

我已使用以下命令重新加载规则:

>sudo udevadm control--reload-rules

并重新启动系统,但当我插入 USB 键盘时,原始 xmodmap 仍然被加载,因此键盘布局是错误的,但如果我在终端中运行命令

>/usr/bin/xmodmap ~/.usbXmodmap
或者
>/usr/bin/xmodmap ~/.pndXmodmap

它们工作得很好。

希望有人可以帮忙。

编辑:

为了提供更多帮助,我运行了一些 udevadm 测试:

>udevadm 测试 --action=add /devices/platform/ehci-omap.0/usb1/1-2/1-2.3/1-2.3:1.1/input/input10

输出:

run_command:调用:测试
udevadm_test:版本 151
该程序仅用于调试,它不运行任何程序,
指定 RUN 键。它可能会显示不正确的结果,因为
某些值可能不同,或者在模拟运行时不可用。

[...]
parse_file:读取‘/etc/udev/rules.d/usb-keyboard.rules’作为规则文件
udev_rules_new:规则使用 100572 字节标记(8381 * 12 字节),21523 字节缓冲区
udev_rules_new:临时索引使用了 35380 字节(1769 * 20 字节)
udev_device_new_from_syspath:设备 0x3b4d8 具有 devpath '/devices/platform/ehci-omap.0/usb1/1-2/1-2.3/1-2.3:1.1/input/input10'
udev_rules_apply_to_event:运行'/sbin/modprobe -b $env{MODALIAS}'/etc/udev/rules.d/80-drivers.rules:5
udev_rules_apply_to_event:运行'socket:@/org/freedesktop/hal/udev_event'/etc/udev/rules.d/90-hal.rules:2
udev_rules_apply_to_event:运行'/sbin/modprobe $env{MODALIAS}'/etc/udev/rules.d/local.rules:31
udev_rules_apply_to_event:运行'socket:/org/kernel/udev/monitor'/etc/udev/rules.d/run.rules:2
udev_rules_apply_to_event:运行'/usr/bin/xmodmap ~/.usbXmodmap'/etc/udev/rules.d/usb-keyboard.rules:4
udevadm_test:UDEV_LOG=6
udevadm_test:DEVPATH = /设备/平台/ehci-omap.0/usb1/1-2/1-2.3/1-2.3:1.1/输入/输入10
udevadm_test:产品=3/62a/201/110
udevadm_test: NAME="USB 兼容键盘"
udevadm_test:PHYS="usb-ehci-omap.0-2.3/input1"
udevadm_test:UNIQ=””
udevadm_test:EV==1f
udevadm_test:密钥==837fff 2c3027 bf004444 0 0 1fe3 c04 a27c000 267bfa d941dfed 9e0000 0 0 0
udevadm_test:REL==143
udevadm_测试:ABS==1 0
udevadm_test:MSC==10
udevadm_test:MODALIAS=输入:b0003v062Ap0201e0110-e0,1,2,3,4,k71,72,73,74,77,80,82,83,85,86,87,88,89,8A,8B,8C, 8E,8F,90,96,98,9B,9C,9E,9F,A1,A3,A4,A5,A6,A7,A8,A9,AB,AC,AD,AE,B1,B2,B5,CE, CF,D0,D1,D2,D5,D9,DB,E2,EA,EB,100,1 01,105,106,107,108,109,10A,10B,10C,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,r0,1,6,8,a20,m4,lsfw
udevadm_test:ACTION=添加
udevadm_test:子系统=输入
udevadm_test:运行:'/sbin/modprobe -b 输入:b0003v062Ap0201e0110-e0,1,2,3,4,k71,72,73,74,77,80,82,83,85,86,87,88,89 ,8A,8B,8C,8E,8F,90,96,98,9B,9C,9E,9F,A1,A3,A4,A5,A6,A7,A8,A9,AB,AC,AD,AE,B1 ,B2,B5,CE,CF,D0,D1,D2,D5,D9,DB,E2,EA,EB,100,101,10 5,106,107,108,109,10A,10B,10C,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,r0,1,6,8,a20,m4,lsfw'
udevadm_test:运行:'socket:@/org/freedesktop/hal/udev_event'
udevadm_test:运行:'/sbin/modprobe 输入:b0003v062Ap0201e0110-e0,1,2,3,4,k71,72,73,74,77,80,82,83,85,86,87,88,89,8A ,8B,8C,8E,8F,90,96,98,9B,9C,9E,9F,A1,A3,A4,A5,A6,A7,A8,A9,AB,AC,AD,AE,B1,B2 ,B5,CE,CF,D0,D1,D2,D5,D9,DB,E2,EA,EB,100,101,10 5,106,107,108,109,10A,10B,10C,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,r0,1,6,8,a20,m4,lsfw'
udevadm_test:运行:'socket:/org/kernel/udev/monitor'
udevadm_test:运行:'/usr/bin/xmodmap ~/.usbXmodmap'

>udevadm 测试 --action=删除 /devices/platform/ehci-omap.0/usb1/1-2/1-2.3/1-2.3:1.1/input/input10

输出:

run_command:调用:测试
udevadm_test:版本 151
该程序仅用于调试,它不运行任何程序,
指定 RUN 键。它可能会显示不正确的结果,因为
某些值可能不同,或者在模拟运行时不可用。

[...]
parse_file:读取‘/etc/udev/rules.d/usb-keyboard.rules’作为规则文件
udev_rules_new:规则使用 100572 字节标记(8381 * 12 字节),21523 字节缓冲区
udev_rules_new:临时索引使用了 35380 字节(1769 * 20 字节)
udev_device_new_from_syspath:设备 0x3b4d8 具有 devpath '/devices/platform/ehci-omap.0/usb1/1-2/1-2.3/1-2.3:1.1/input/input10'
udev_rules_apply_to_event:运行'socket:@/org/freedesktop/hal/udev_event'/etc/udev/rules.d/90-hal.rules:2
udev_rules_apply_to_event:运行'socket:/org/kernel/udev/monitor'/etc/udev/rules.d/run.rules:2
udev_rules_apply_to_event:运行'/usr/bin/xmodmap ~/.pndXmodmap'/etc/udev/rules.d/usb-keyboard.rules:5
udevadm_test:UDEV_LOG=6
udevadm_test:DEVPATH = /设备/平台/ehci-omap.0/usb1/1-2/1-2.3/1-2.3:1.1/输入/输入10
udevadm_test:产品=3/62a/201/110
udevadm_test: NAME="USB 兼容键盘"
udevadm_test:PHYS="usb-ehci-omap.0-2.3/input1"
udevadm_test:UNIQ=””
udevadm_test:EV==1f
udevadm_test:密钥==837fff 2c3027 bf004444 0 0 1fe3 c04 a27c000 267bfa d941dfed 9e0000 0 0 0
udevadm_test:REL==143
udevadm_测试:ABS==1 0
udevadm_test:MSC==10
udevadm_test:MODALIAS=输入:b0003v062Ap0201e0110-e0,1,2,3,4,k71,72,73,74,77,80,82,83,85,86,87,88,89,8A,8B,8C, 8E,8F,90,96,98,9B,9C,9E,9F,A1,A3,A4,A5,A6,A7,A8,A9,AB,AC,AD,AE,B1,B2,B5,CE, CF,D0,D1,D2,D5,D9,DB,E2,EA,EB,100,1 01,105,106,107,108,109,10A,10B,10C,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,r0,1,6,8,a20,m4,lsfw
udevadm_test:ACTION=删除
udevadm_test:子系统=输入
udevadm_test:运行:'socket:@/org/freedesktop/hal/udev_event'
udevadm_test:运行:'socket:/org/kernel/udev/monitor'
udevadm_test:运行:'/usr/bin/xmodmap ~/.pndXmodmap'

这似乎表明它应该可以工作,但并不希望这有助于得到答案。

答案1

我找到了一种解决这个问题的方法,尽管它有点不准确。

今天,我尝试使用 udev、setxkbmap 和 xinput --list 设置两个键盘,并使它们能够与 USB 热插拔配合使用,但遇到了完全相同的问题。我交换了按键,没有改变布局,但都是一样的,一旦您在热插拔时识别了键盘,并且可以有条件地调用 setxkbmap,那么您应该能够仅设置您指定的键盘的语言。键盘布局列表可以在此处找到,ls -l /usr/share/kbd/keymaps/i386/您可以找到要使用的设备名称xinput -list

  1. 您需要用rizumu您的用户名进行替换,因为我发现如果不明确说明就无法做到这一点。
  2. 确保您在your键盘名称上找到 grep。
  3. 用于lsusb发现您需要在 udev 规则中设置的硬件 ID。我的 das 键盘如下所示Bus 002 Device 009: ID 04d9:2013 Holtek Semiconductor, Inc.

我首先通过创建 udev 规则来设置 udev 规则以自动检测键盘:

在文件中/etc/udev/rules.d/00-usb-keyboards.rules

ACTION=="add", ATTRS{idVendor}=="04d9", ATTRS{idProduct}=="2013", RUN+="/home/rizumu/bin/kbd_udev", OWNER="rizumu"

我有两个文件 ~/bin/kbd 和 ~/bin/kbd_udev。确保它们具有正确的权限chmod 755 ~/bin/kbd*

~/bin/kbd_udev脚本包含:

#!/bin/bash
/home/rizumu/bin/kbd &

您会注意到,它所做的只是~/bin/kbd在后台调用,以便 udev 可以完成其进程并激活键盘。在脚本中,我们休眠一秒钟,因为我们需要等到键盘激活,这样我们才能使用 xinput 获取设备 ID。为了实现这一点,~/bin/kbd我设置了一些变量并将它们导出,以便 xinput setxkbmap 可以完成它们的工作:DISPLAY,,,,以及一个用于我的 daskeyboard 的 ID:XAUTHORITYHOMEdaskb_id

#!/bin/bash
sleep 1
DISPLAY=":0.0"
HOME=/home/rizumu/
XAUTHORITY=$HOME/.Xauthority
export DISPLAY XAUTHORITY HOME
daskb_id=`xinput -list | grep -i 'daskeyboard' | grep -o id=[0-9]. | grep -o [0-9]. | head -1`

xset r rate 200 30
setxkbmap -layout colemak
setxkbmap -option ctrl:nocaps
if [ "${daskb_id}" ]; then
    setxkbmap -device "${daskb_id}" -option altwin:swap_lalt_lwin
fi

答案2

根据您的发行版,您可能已经在 /lib/udev/rules.d/64-xorg-xkb.rules 中为键盘设置了 udev 规则。在 Ubuntu 上,这会导入 /etc/default/keyboard,其中的选项大致如下:

XKBMODEL="pc105"
XKBLAYOUT="us"
XKBVARIANT=""
XKBOPTIONS=""

对于我的设置,我发现此内置规则在我的自定义 udev 规则之后执行,并覆盖了我的设置。相反,我将 /etc/default/keyboard 中的 XKBOPTIONS 更改为:

XKBOPTIONS="-option ctrl:nocaps"

为了在所有键盘上获得我想要的“Caps Lock 是 Control”行为。

答案3

如果您正在运行 GNOME,那么您需要禁用其键盘管理插件,以便它不会覆盖您的布局更改。

gconftool-2 --toggle /apps/gnome_settings_daemon/plugins/keyboard/active

再次运行相同的命令以根据需要启用它。

答案4

要回答有关访问正在运行的显示的问题,您可以导出脚本中的相应 DISPLAY 变量,假设显示的权限已正确设置。(man xset用于显示权限。)

在许多常见情况下,您可以简单地export DISPLAY=:0输入命令,因为这是单用户系统上的第一个显示。运行脚本而不是直接运行 xmodmap 可能最容易,因为这将允许您更好地控制环境变量和其余部分。(因此,将规则中的“/usr/bin/xmodmap ~/.usbXmodmap”替换为“/usr/local/bin/keyboard_plug.sh”,并将适当的命令与 DISPLAY 变量一起放入该脚本中。)

但是如上所述,如果您假设 DISPLAY=:0,那么如果您有多个用户或显示器,那么以后可能会遇到问题。您可以编写脚本来检测适当的显示器,但在这种情况下,您只能靠自己了(就这个答案而言)。:)

相关内容