Ubuntu 22.04系后台脚本按键检测异常问题求助
后台开机自启键盘超时脚本解决方案
需求说明
- 脚本存放路径:
/etc/init.d,需设置开机自启 - 核心逻辑:等待指定时长X秒后执行命令;检测到按键操作时,执行另一命令并重置等待时长(类似键盘超时熄灯、按键唤醒的逻辑)
- 运行环境:基于Ubuntu 22.04的Linux Mint Victoria 21.2,暂未添加鼠标检测逻辑
现有脚本问题分析
第一段脚本(read命令实现)
终端测试正常,但后台运行时刚完成sleep 20就触发按键检测循环异常。
代码:
#!/bin/bash while true; do sleep 1 read -rsn1 input if [ "$input" = "ł" ]; then echo "this is a key that you can't press" else echo "you press " "$input" # command to run here if key has been pressed fi sleep 20 # command to run here after 20 secodns if key has not been pressed done trap control_c SIGINT control_c() { stty sane } exit 0
问题根源:read命令依赖终端标准输入,后台运行时stdin不再指向终端,导致read无法正常阻塞等待按键,进而打乱循环逻辑。
第二段脚本(evemu-record实现)
终端测试正常,但后台运行无法获取键盘反馈。
代码:
#!/bin/bash start=$SECONDS while true; do sleep 1 input=$(sudo timeout 5s evemu-record /dev/input/event3 | grep "EV_KEY / KEY") duration=$(( SECONDS - start )) if [ "$input" = "" ]; then if (( $duration > 30 )); then # command to run here fi else # command to run here input="" duration=$(( SECONDS - duration )) fi done trap control_c SIGINT control_c() { stty sane }
问题根源:后台进程缺少输入设备访问权限,且evemu-record在非终端环境下输出行为异常;硬编码/dev/input/event3也不够灵活,设备路径可能随系统变动。
修复后的脚本方案
采用evtest工具实现(比evemu-record更轻量,适配后台运行场景),解决权限和逻辑问题:
步骤1:安装依赖工具
sudo apt install evtest
步骤2:创建脚本(/etc/init.d/keyboard_timeout.sh)
#!/bin/bash # 配置参数 TIMEOUT=20 # 设置超时秒数 # 自动检测键盘设备路径 KEYBOARD_EVENT=$(grep -E 'Handlers|EV=' /proc/bus/input/devices | grep -B1 'EV=120013' | grep -Eo 'event[0-9]+') KEYBOARD_DEVICE="/dev/input/$KEYBOARD_EVENT" # 确保脚本有权限访问输入设备 if [ ! -r "$KEYBOARD_DEVICE" ]; then sudo chmod a+r "$KEYBOARD_DEVICE" fi # 初始化超时计数器 timeout_counter=0 # 循环监听按键事件 evtest "$KEYBOARD_DEVICE" | while read -r line; do # 检测按键按下动作 if echo "$line" | grep -q "EV_KEY.*value 1"; then # 按键触发时执行的自定义命令 echo "按键触发,重置超时计数器" >> /var/log/keyboard_timeout.log # 替换为你的实际命令,例如:systemctl start some-service timeout_counter=0 else # 无按键时递增计数器 sleep 1 ((timeout_counter++)) # 超时触发自定义命令 if ((timeout_counter >= TIMEOUT)); then echo "超时触发指定命令" >> /var/log/keyboard_timeout.log # 替换为你的实际命令,例如:systemctl stop some-service timeout_counter=0 fi fi done # 捕获退出信号,确保进程正常终止 trap 'kill $!; exit 0' SIGINT SIGTERM
步骤3:配置开机自启
- 给脚本添加执行权限:
sudo chmod +x /etc/init.d/keyboard_timeout.sh
- 添加到开机自启服务:
sudo update-rc.d keyboard_timeout.sh defaults
方案优势
- 用
evtest直接读取输入设备事件,不依赖终端stdin,适配后台运行 - 自动检测键盘设备路径,避免硬编码设备号的问题
- 提前处理输入设备权限,确保后台进程能正常读取按键事件
- 逻辑清晰:按键触发时重置计数器,超时则执行目标命令
内容的提问来源于stack exchange,提问作者User-285
相关产品推荐
相关产品推荐

