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
我会使用 idVendor
和 idProduct
您可以通过连接键盘并使用 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
我正在编写一个 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
我会使用 idVendor
和 idProduct
您可以通过连接键盘并使用 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