Bash - 如何在 USB 设备连接时 运行 编码

Bash - How to run code whenever USB device is connected

我正在编写一个 bash 脚本来自动检测我的 USB 键盘何时插入我的笔记本电脑 (运行ning Ubuntu 14),因此我可以自动更改键盘布局.

这是我目前的代码(我是从 Stack Overflow 上的另一个 post 得到的,所以我不是 100% 确定它是如何工作的)

#!/bin/bash
setxkbmap es
for dev in /sys/bus/usb/devices/ *-*:*
do
    if [ -f $dev/bInterfaceClass ]
    then
        if [[ "$(cat $dev/bInterfaceClass)" == "03" && "$(cat $dev/bInterfaceProtocol)" == "01" ]]
        then
            setxkbmap gb
        fi
    fi
done

到目前为止,我已经在启动时将其设置为 运行...但我希望每次连接或断开 USB 设备时都设置为 运行。

重要的是,我将所有内容 运行 都放在一个 Bash 脚本 中,而不是作为 ...udev/ 中的 .rules 文件。 .. 或任何东西。但是,单个 Python 脚本也可以。

这是有效的,因为在 linux 系统上文件系统结构总是相同的

cat $dev/bInterfaceClass 查询每个 USB 设备的 接口 class

cat $dev/bInterfaceProtocol 查询每个 USB 设备的 接口协议

尝试ls /sys/bus/usb/devices/,您会看到所有 USB 设备节点

然后 select 一个,即 ls /sys/bus/usb/devices/usb1 并使用 ls /sys/bus/usb/devices/usb1/idVendor

而不是 bInterfaceProtocol 我会使用 idVendoridProduct 您可以通过连接键盘并使用 lsusb 和选择来确定键盘的产品 ID 和供应商 ID它来自列表

更新

以下脚本将执行此操作。插入设备的供应商和产品 ID。也许在没有 setxkbmap 命令之前进行测试。 flag 变量用于不每 5 秒设置一次键盘映射 ...

#!/bin/bash

flag=0


while true

do

for dev in /sys/bus/usb/devices/*-*
do
    if [ -f $dev/idVendor ]
    then
        if [[ "$(cat $dev/idVendor)" == "your_vendor_id" && "$(cat $dev/idProduct)" == "your_product_id" ]]
        then
            if [[ "$flag" == "0" ]]
              then
                echo 'USB device attached'
                 setxkbmap gb
            fi
            flag=1
            break
        fi 
            if [[ "$flag" == "1" ]]
               then
                 echo 'USB device detached'
                 setxkbmap es
            fi
            flag=0
    fi

 done

  sleep 5s

done

请注意,要使 setxkbmap 正常工作,您必须安装 x11-xkb-utils

( https://superuser.com/questions/404457/how-to-change-keyboard-layout-while-in-console )

感谢 ralf htp 我能够想出以下解决方案。 它有以下改进:

  • 它不依赖于特定的键盘,它会以同样的方式对待所有的 USB 键盘。
  • 如果用户手动切换到不同的键盘布局(既不是默认键盘布局也不是 USB 键盘布局),它不会自动切换回默认布局或 USB 布局。

请随时在 GitHub Gist

处改进此代码
#!/bin/bash
kbd1=es #default keyboard layout
kbd2=gb #USB keyboard layout

flag=0
while true
do
    layout="$(setxkbmap -query | grep -a layout | cut -c13-14)"
    if [[ $layout == $kbd1 ]] || [[ $layout == $kbd2 ]]
    then
        for dev in /sys/bus/usb/devices*-*
        do
            if [ -f $dev/bInterfaceClass ]
            then
                if [[ "$(cat $dev/bInterfaceClass)" == "03" && "$(cat 
$dev/bInterfaceProtocol)" == "01" ]]
                then
                    if [[ "$flag" == "0" ]]
                    then
                            setxkbmap $kbd2
                    fi
                    flag=1
                    break
                fi 
                if [[ "$flag" == "1" ]]
                then
                    setxkbmap $kbd1
                fi
                flag=0
            fi
        done
    fi
    sleep 5s
done