Обнаружение клавиатуры Ubuntu из скрипта bash
Извините за мое незнание проблем ОС Linux / оборудования... Я просто программист:)
У меня есть приложение, которое вызывает некоторые сценарии bash для запуска внешних приложений, в данном случае Firefox. Приложение работает в киоске с возможностью сенсорного экрана. При запуске Firefox я также запускаю приложение виртуальной клавиатуры, которое позволяет пользователю вводить данные с клавиатуры.
Тем не менее, киоск также имеет слоты PS/2 и USB, которые позволят пользователю подключить клавиатуру. Если бы клавиатура была подключена, было бы неплохо, если бы мне не нужно было запускать виртуальную клавиатуру и выделять больше места на экране для окна Firefox.
Есть ли способ определить, подключена ли клавиатура из скрипта bash? Будет ли он отображаться в / dev, и если да, будет ли он отображаться в согласованном месте? Будет ли иметь значение, если пользователь будет использовать клавиатуру PS/2 или USB?
Спасибо!
5 ответов
Для устройства USB вы можете использовать lsusb
и поиск устройства интерфейса пользователя (интерфейсный класс 3) с протоколом клавиатуры (интерфейсный протокол 1), например
$ lsusb -v
... loads of stuff deleted ...
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 1 Boot Interface Subclass
bInterfaceProtocol 1 Keyboard
iInterface 0
... loads of stuff deleted ...
Кроме того, вы можете позволить udev
помочь тебе. Перечислите устройства под /dev/input/by-path/
и клавиатура устройства заканчиваются -kdb
(по крайней мере, в Ubuntu, где это указано в правилах udev), например
$ ls -l /dev/input/by-path/*-kbd
lrwxrwxrwx 1 root root 9 2010-03-25 09:14 /dev/input/by-path/pci-0000:00:1a.2-usb-0:1:1.0-event-kbd -> ../event4
$ ls -l /dev/input/by-path/*-kbd
lrwxrwxrwx 1 root root 9 2009-08-29 09:46 /dev/input/by-path/platform-i8042-serio-0-event-kbd -> ../event1
Что касается USB-клавиатур, я обычно нахожу устройство клавиатуры простым поиском в слове "lsusb -v" слова "Клавиатура":
lsusb -v 2>/dev/null | egrep '(^Bus|Keyboard)' | grep -B1 Keyboard
Пример вывода:
Bus 001 Device 004: ID 413c:2006 Dell Computer Corp.
bInterfaceProtocol 1 Keyboard
Более общий метод заключается в поиске /sys/bus для любого устройства, которое является одновременно bInterfaceClass 03 и bInterfaceProtocol 01. Поскольку вам необходимо обнаруживать устройства, отличные от USB, и вы хотите использовать выходные данные в сценарии, этот метод, вероятно, будет работать лучше. для тебя:
grep -l 03 /sys/bus/*/*/*/bInterfaceClass |
sed 's/Class$/Protocol/' |
xargs grep -l 01 |
xargs dirname
Пример вывода:
/sys/bus/usb/devices/1-4.1:1.0
Предостережение: я не могу найти клавиатуру PS/2 для тестирования этого скрипта. Поскольку этой ветке уже более семи лет, я предполагаю, что автор оригинального вопроса давно ушел и больше не нуждается в обнаружении PS/2. В любом случае, я оставлю этот ответ в надежде, что кто-то еще сочтет его полезным, но учтите, что я не проверял его на устройствах, не поддерживающих USB.
Клавиатуры PS/2 перечислены среди /sys/class/input
устройства. Там также могут присутствовать USB-клавиатуры, потому что ниже указана мышь USB:
$ grep "" /sys/class/input/*/name
/sys/class/input/input0/name:Power Button
/sys/class/input/input1/name:Power Button
/sys/class/input/input2/name:AT Translated Set 2 keyboard
/sys/class/input/input3/name:Microsoft Comfort Mouse 6000
$ grep keyboard /sys/class/input/*/name
/sys/class/input/input2/name
Еще одно открытие состоит в том, что каталоги клавиатуры содержат подкаталоги для статусных клавиш:
$ ls -d /sys/class/input/*/*::capslock
/sys/class/input/input2/input2::capslock
Для USB вы можете искать /sys/bus/usb/devices для устройства с конфигурацией с интерфейсом с классом HID (0x03) и протоколом Keyboard (0x01).
Bash скрипт:
#!/bin/bash
for dev in /sys/bus/usb/devices/*-*:*
do
if [ -f $dev/bInterfaceClass ]
then
if [[ "$(cat $dev/bInterfaceClass)" == "03" && "$(cat $dev/bInterfaceProtocol)" == "01" ]]
then
echo "Keyboard detected: $dev"
fi
fi
done