运维笔记

Linux 按键映射守护进程 keyd 深度实战:告别 xmodmap,拥抱现代内核级方案

Infrastructure 技术可视化

前言:为什么我们还在折腾按键映射?

老实说,Linux 的按键映射一直是个老大难。我见过太多人在 xmodmapsetxkbmap 的泥潭里挣扎,换到 Wayland 后这些老古董直接报废。更别提那些需要“长按变修饰键,短按是普通键”的高级玩法——传统方案基本没戏。

上个月 Hacker News 上 keyd 项目又火了一把(69 points,33 条评论),这说明啥?说明大家还在被这个问题折磨。我自己的经历也差不多:去年换了把 HHKB,想把右 Ctrl 映射成 Backspace,试了一圈方案,最后被 keyd 的简洁和稳定征服了。

keyd 到底是什么?

简单说,keyd 是一个系统级的按键映射守护进程,直接工作在 Linux 内核的输入子系统层面(evdev + uinput)。这意味着它不依赖 X11 还是 Wayland,也不管你用的是 GNOME、KDE 还是 i3——通吃。

它的核心卖点有三个:

  1. 真正的系统级:不依赖显示服务器
  2. 支持按键层和按键重载:比如按住 Fn 键切换层,或者短按 Ctrl 是 Ctrl,长按变成 Super
  3. 性能极佳:C 语言编写,内存占用不到 2MB

安装:比想象中简单

我测试的环境是 Arch Linux,但 Ubuntu 和 Fedora 也大同小异。

# Arch Linux
yay -S keyd

# 或者从源码编译
git clone https://github.com/rvaiya/keyd.git
cd keyd
make && sudo make install
sudo systemctl enable keyd --now

装完先检查一下服务状态:

sudo systemctl status keyd

如果看到 active (running),恭喜,你已经成功了一半。

配置文件:这才是精髓

keyd 的配置文件在 /etc/keyd/default.conf。别被它吓到,语法其实很直观。

场景一:把 Caps Lock 变成 Ctrl

这是最经典的需求,很多 Vim 用户的刚需:

[ids]

[main]
capslock = leftcontrol

就这么两行。重启 keyd 服务生效:

sudo systemctl restart keyd

场景二:右 Alt 变成 Compose Key

[ids]

[main]
rightalt = compose

场景三:长按 Ctrl 变 Super,短按还是 Ctrl(按键重载)

这才是 keyd 的真本事:

[ids]

[main]
control = overload(control, super)

解释一下:短按时,它表现得像个普通的 Ctrl 键。长按(超过默认的 200ms),它就变成了 Super 键。这个功能在 Emacs 用户里特别受欢迎——左手小拇指不用再够那个别扭的 Super 键了。

场景四:自定义 Layer

比如我想把右手的 Home Row 在按住 Fn 时变成方向键:

[ids]

[main]
rightalt = layer(custom)

[custom]
j = left
k = down
l = right
i = up

这体验,直逼 QMK 固件的可编程键盘。

踩坑记录:不是所有配置都一帆风顺

1. 蓝牙键盘问题

我第一把蓝牙键盘连上后,keyd 死活不认。原因是 [ids] 段没写对。解决方案是用 sudo keyd monitor 查看设备信息:

$ sudo keyd monitor
/dev/input/event5: Apple Wireless Keyboard

然后在配置里指定:

[ids]
0001:0005  # Vendor:Apple, Product:Wireless Keyboard

2. 和 i3 的冲突

i3 的配置文件里如果也绑定了某些键,会和 keyd 打架。我的经验是:把按键映射全交给 keyd,i3 只负责窗口管理。这样逻辑清晰,出了问题也好排查。

3. SSH 远程会话

keyd 只在本地生效。你在 SSH 到远程服务器时,按键映射不会跟着走。这是设计使然,不是 bug——远程服务器的输入处理链根本不在你的机器上。

性能对比:keyd vs 其他方案

特性keydxmodmapsetxkbmapudev hwdb
内核级
Wayland 支持
按键层
按键重载
热插拔支持
配置简单度⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
内存占用~1.5MB~0.5MB~1MB0
调试工具keyd monitorxevudevadm monitor

很明显,keyd 在功能丰富度和现代兼容性上完胜。唯一缺点是多了一个守护进程,但 1.5MB 的代价几乎可以忽略不计。

进阶技巧:多设备差异化配置

你可能有多个键盘,想给不同的键盘配不同的映射。keyd 支持按设备 ID 配置:

# /etc/keyd/apple-keyboard.conf
[ids]
05ac:0250

[main]
rightalt = compose
# /etc/keyd/hhkb.conf
[ids]
0853:0110

[main]
leftctrl = backspace
rightalt = layer(navigation)

系统会自动匹配。这比 udev hwdb 那种“改个规则要重启 udev”的体验好太多了。

常见问题 FAQ

Q: keyd 和 udev hwdb 有什么区别? A: udev hwdb 是内核级别的按键修正,但它不支持层、重载这些高级功能。keyd 在用户态运行,但通过 uinput 模拟内核输入,所以兼容性一样好,功能却丰富得多。

Q: 为什么我配置了 keyd 但没生效? A: 最常见的原因是权限问题。确保 keyd 服务在运行,并且你的用户有权限访问 /dev/uinput。可以用 sudo keyd monitor 调试。

Q: keyd 会影响游戏吗? A: 不会。keyd 在映射层完成工作,游戏看到的还是标准的按键事件。不过如果你在游戏里需要原生的按键行为,建议在配置里加上 [games] 段来排除。

Q: 和 kmonad 比怎么样? A: kmonad 也是好项目,但它是 Haskell 写的,配置语法更复杂。keyd 的 C 实现性能和稳定性都更好,配置也更直观。

总结与建议

keyd 是我用过的最顺手的 Linux 按键映射方案。它解决了我在 X11/Wayland 之间反复横跳的痛点,也让我那些“非标”的按键习惯有了归宿。

如果你还在用 xmodmap,我建议你趁早迁移。Wayland 的普及是迟早的事,到时候老方案全得翻车。keyd 的学习成本很低,一两个小时就能上手,换来的是未来几年的无痛使用。

最后给几个最佳实践:

  • 调试时始终用 sudo keyd monitor 实时查看按键事件
  • 复杂配置建议按设备拆分文件,方便管理
  • 升级 keyd 后重启服务,偶尔会有配置格式变化

Hacker News 上那 33 条评论里,有人抱怨 keyd 的文档不够详细。我承认,官方文档确实偏简洁,但结合我这篇文章,你应该能搞定 90% 的场景。剩下的 10%,欢迎留言讨论。