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

如何为含循环的BASH脚本添加鼠标启停切换并修复合并问题?

合并BASH鼠标切换开关与动作循环脚本的解决方案

合并脚本后无法正确跳出内部循环的核心原因是:单线程顺序执行时,鼠标监听循环和动作循环会互相阻塞——当脚本在执行动作内部循环时,无法同时监听鼠标按键事件,导致toggle文件的状态变化不能被及时检测到,反之亦然。

下面是修复后的合并脚本,通过后台子进程处理鼠标监听,让主进程专注于动作循环,两者互不阻塞,同时保证toggle状态的实时响应:

#!/bin/bash

# 防止多实例运行
PIDS=$(pidof -o $$ -x "$0")
if [ -n "$PIDS" ]; then
    exit 0
fi

# 定义toggle文件路径
TOGGLE="$HOME/.toggle"
# 初始化toggle文件(默认开启状态)
[ ! -e "$TOGGLE" ] && touch "$TOGGLE"

# 检测鼠标设备
if xinput --list | grep -q "My Mouse Label 1"; then
    pointerLabel="My Mouse Label 1"
else
    pointerLabel="My Mouse Label 2"
fi
pointerDevice=$(xinput --list --id-only "$pointerLabel")

# 检测键盘设备
keyboardLabel="My Keyboard"
keyboardDevice=$(xinput --list --id-only "$keyboardLabel")

# --------------------------
# 后台子进程:监听鼠标按键,切换toggle状态
# --------------------------
(
    while true; do
        state_mouse=$(xinput --query-state "$pointerDevice")
        if [[ "$state_mouse" == *"button[8]=down"* ]]; then
            if [ -f "$TOGGLE" ]; then
                rm -f "$TOGGLE"
                echo "Toggle Off"
            else
                touch "$TOGGLE"
                echo "Toggle On"
            fi
            sleep 0.5  # 防止按键重复触发
        fi
        # 短暂休眠,降低CPU占用
        sleep 0.05
    done
) &
# 记录后台进程PID,用于脚本退出时清理
mouse_pid=$!

# --------------------------
# 主进程:动作循环
# --------------------------
action() {
    while [ -f "$TOGGLE" ]; do
        state=$(xinput --query-state "$keyboardDevice" | grep 'down')
        if [ -n "$state" ]; then
            case "$state" in
                *"key[10]=down"*) xdotool key --clearmodifiers 1 ;;
                *"key[11]=down"*) xdotool key --clearmodifiers 2 ;;
                *"key[12]=down"*) xdotool key --clearmodifiers 3 ;;
            esac
            break  # 处理一次按键后退出子循环,回到主循环重新检测toggle状态
        fi
        sleep 1
    done
}

# 主循环
while true; do
    action
done

# 脚本退出时清理后台进程(如果脚本被正常终止)
trap "kill $mouse_pid" EXIT

关键改动说明:

  • 后台子进程处理鼠标监听:把鼠标按键检测逻辑放到后台异步运行,主进程和子进程并行执行,避免互相阻塞。
  • 降低CPU占用:在鼠标监听循环中添加短暂休眠,避免无限空循环消耗过多系统资源。
  • 实时响应toggle状态:动作内部循环每次都会检查toggle文件的存在性,一旦开关被关闭,会立即跳出循环。
  • 进程清理:通过trap命令捕获脚本退出信号,自动终止后台的鼠标监听进程,避免残留僵尸进程。

内容的提问来源于stack exchange,提问作者proxyx

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 01:20:21