You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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:配置开机自启

  1. 给脚本添加执行权限:
sudo chmod +x /etc/init.d/keyboard_timeout.sh
  1. 添加到开机自启服务:
sudo update-rc.d keyboard_timeout.sh defaults

方案优势

  • 用evtest直接读取输入设备事件,不依赖终端stdin,适配后台运行
  • 自动检测键盘设备路径,避免硬编码设备号的问题
  • 提前处理输入设备权限,确保后台进程能正常读取按键事件
  • 逻辑清晰:按键触发时重置计数器,超时则执行目标命令

内容的提问来源于stack exchange,提问作者User-285

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 02:20:28