Linux下非鼠标/键盘类USB外设(如扫描仪按键)的输入事件定位与监听处理问题
嗨,这个问题我之前也碰到过!带按键的外设经常会在Linux上注册成独立的输入事件设备,只是不像鼠标键盘那样容易被直接关联到。下面是一步步帮你定位并监听扫描仪按键事件的方法:
第一步:安装必要的工具
首先我们需要两个工具来枚举和测试输入设备:evtest(用来实时监听输入事件)和input-utils(用来列出所有输入设备的详细信息)。在Debian/Ubuntu系系统上可以用下面的命令安装:
sudo apt update && sudo apt install evtest input-utils
如果是RedHat/CentOS/Fedora系,则用:
sudo dnf install evtest input-utils
第二步:找到扫描仪对应的输入设备
运行lsinput命令,它会列出系统中所有的输入设备,包括每个设备的名称、对应的/dev/input/eventX路径以及支持的事件类型。你需要在列表里找带有你扫描仪型号(比如“ES-50 USB Scanner”)的条目,记下它对应的event设备路径(比如/dev/input/event7)。
如果lsinput的输出不够明确,你也可以直接运行evtest,它会先让你选择要测试的设备:
sudo evtest
输入对应的设备编号,然后按下扫描仪上的大按键——如果这个设备是负责按键事件的,你会看到终端输出类似按键按下/释放的事件日志,比如:
Event: time 1699999999.999999, type 1 (EV_KEY), code 28 (KEY_ENTER), value 1 Event: time 1699999999.999999, -------------- SYN_REPORT ------------ Event: time 1700000000.000000, type 1 (EV_KEY), code 28 (KEY_ENTER), value 0 Event: time 1700000000.000000, -------------- SYN_REPORT ------------
这样就确认了这个设备就是我们要找的目标。
第三步:监听事件并触发扫描命令
找到目标设备后,你可以选择两种方式来处理事件:
方式一:用Python脚本监听(推荐)
我们可以用Python的evdev库来轻松监听事件并执行扫描命令。先安装库:
sudo apt install python3-evdev
然后写一个简单的脚本(比如scan_button_listener.py):
from evdev import InputDevice, categorize, ecodes import subprocess import os # 替换成你找到的扫描仪按键设备路径 device = InputDevice('/dev/input/event7') # 确保扫描输出目录存在 SCAN_DIR = os.path.expanduser("~/scans") os.makedirs(SCAN_DIR, exist_ok=True) # 扫描命令,根据你的扫描仪调整,比如scanimage或者品牌专用命令 SCAN_CMD = f"scanimage --format=png > {SCAN_DIR}/$(date +%Y%m%d_%H%M%S).png" print(f"监听扫描仪按键事件...") for event in device.read_loop(): if event.type == ecodes.EV_KEY: key_event = categorize(event) # 这里的KEY_ENTER要替换成你在evtest里看到的按键码 if key_event.keycode == 'KEY_ENTER' and key_event.keystate == key_event.key_down: print("检测到按键按下,开始扫描...") subprocess.run(SCAN_CMD, shell=True)
运行脚本:
sudo python3 scan_button_listener.py
按下扫描仪按键,就能自动触发扫描了!
方式二:直接用evtest配合Shell脚本
如果你不想用Python,也可以用evtest的输出配合Shell脚本过滤事件,比如:
# 替换成你的设备路径 EV_DEVICE="/dev/input/event7" # 替换成你的扫描命令 SCAN_CMD="scanimage --format=png > ~/scans/$(date +%Y%m%d_%H%M%S).png" sudo evtest $EV_DEVICE | grep -A2 "KEY_ENTER.*value 1" | while read -r line; do if [[ $line == *"SYN_REPORT"* ]]; then echo "触发扫描..." mkdir -p ~/scans eval $SCAN_CMD fi done
第四步:解决权限问题(可选)
每次用sudo很麻烦?可以把你的用户加入input组,这样就不用sudo也能访问输入设备了:
sudo usermod -aG input $USER
执行完后注销再重新登录,权限就生效了。
第五步:设置开机自动监听(可选)
如果想让这个监听脚本开机自动运行,可以创建一个systemd服务文件,比如/etc/systemd/system/scan-button-listener.service:
[Unit] Description=Scanner Button Listener After=multi-user.target [Service] User=你的用户名 ExecStart=/usr/bin/python3 /home/你的用户名/scan_button_listener.py Restart=always [Install] WantedBy=multi-user.target
然后启用并启动服务:
sudo systemctl daemon-reload sudo systemctl enable scan-button-listener.service sudo systemctl start scan-button-listener.service
这样以后开机后脚本就会自动运行,按下扫描仪按键就能直接触发扫描啦!
备注:内容来源于stack exchange,提问作者John Craig

