Я разрабатываю сценарий bash, который автоматизирует добавление USB-ключа Wi-Fi в виртуальную машину (виртуализация QEmu/KVM) и, следовательно, добавляет ключ Wi-Fi в виртуальную машину.

[edit] Эта виртуальная машина на данный момент с дистрибутивом Debian Buster[/edit]

С хоста, когда я подключаю свой USB-ключ TP-Link TL-WN823N, добавляется следующий интерфейс:

user@host:~$ ip -o link | grep wlx
57: wlx123456789012: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000\    link/ether 2a:51:d5:12:34:56 brd ff:ff:ff:ff:ff:ff

Когда я перечисляю USB-устройства, я получаю:

user@host:~$ lsusb | grep TP-Link
Bus 002 Device 009: ID 2357:0109 TP-Link TL WN823N RTL8192EU

Поэтому он идентифицируется интерфейсом wlx123456789012, его идентификатор поставщика:продукта — 2357:0109 и является устройством #9 шины USB №2.*

Как точно определить поставщика:идентификатор продукта, когда мы знаем только имя интерфейса?

@meuh предложение

user@host:~$ ls --format=commas /sys/class/net/wlx123456789012/device
authorized, bAlternateSetting, bInterfaceClass, bInterfaceNumber,
bInterfaceProtocol, bInterfaceSubClass, bNumEndpoints, driver,
ep_01, ep_02, ep_03, ep_04, ep_05, ep_06, ep_81, ieee80211, leds,
modalias, net, power, subsystem, supports_autosuspend, uevent

Таким образом, ни файл vendor, ни файл device непосредственно в этом месте (по его словам, это связано с тем, что его тест касается встроенного Wi-Fi)

Но это вдохновило меня, поэтому я попробовал:

    user@host:~$ grep -iEr "2357|0109" /sys/class/net/wlx123456789012/device
...
/sys/class/net/wlx123456789012/device/modalias:usb:v2357p0109d0101dc00dsc00dp00icFFiscFFipFFin00
/sys/class/net/wlx123456789012/device/uevent:PRODUCT=2357/0109/101
/sys/class/net/wlx123456789012/device/uevent:MODALIAS=usb:v2357p0109d0101dc00dsc00dp00icFFiscFFipFFin00

Итак, в /sys/class/net/wlx123456789012/device находятся:

Модалии: usb:v2357p0109d0101dc00dsc00dp00icFFiscFFipFFin00

Событие : PRODUCT=2357/0109/101

Так что я нашел следы, но тот факт, что @meuh дает мне другую локализацию, заставляет меня сомневаться, что решение (особенно, если я поменяю версию дистрибутива или просто дистрибутив)

@Том Ян предлагает

user@host:~$ udevadm info /sys/class/net/wlx123456789012 \
 | sort -r | awk '/ID_(VENDOR|MODEL)_ID/'
E: ID_VENDOR_ID=2357
E: ID_MODEL_ID=0109

Примечание: здесь МОДЕЛЬ используется вместо ПРОДУКТА; sort -r используется для сортировки строки ПРОДАВЦА перед строкой МОДЕЛЬ.

1
Le Nain Jaune 2 Авг 2021 в 12:32
1
Это то, что вы хотите в cat /sys/class/net/wlx123456789012/device/{vendor,device}
 – 
meuh
31 Июл 2021 в 18:35
Спасибо ! Я эффективно нашел следы производителя и продукта в папке «устройство». Я отредактировал свой вопрос. Но переносимо ли это решение между версиями Debian или если я сменю дистрибутив?
 – 
Le Nain Jaune
31 Июл 2021 в 19:45
... что указывает на связь между поставщиком: продуктом и результирующим интерфейсом?
 – 
Le Nain Jaune
31 Июл 2021 в 20:01
1
Там udevadm info [-a] кстати. lsusb.py -[c]ui тоже может помочь.
 – 
Tom Yan
1 Авг 2021 в 08:41
Ян: Спасибо! udevadm решил проблему. Я отредактировал свой вопрос, добавив способ udevadm.
 – 
Le Nain Jaune
1 Авг 2021 в 19:49

2 ответа

Лучший ответ

Итак, основываясь на предложении udev @Tom Yan, чтобы перечислить все интерфейсы USB-ключа Wi-Fi с поставщиком: продукт, я предлагаю:

user@host:~$ for i in $( find /sys/class -name "wlx*" ) ; do \
 echo "$( echo $i | grep -oE "[^/]+$" ) $( \
  udevadm info $i \
  | awk '\
   function get_val () { split ( $0 , a , "=" ) ; return a [ 2 ] } \
   /ID_VENDOR_ID/ { v = get_val() } \
   /ID_MODEL_ID/ { m = get_val() } \
   END { print v ":" m }\
  ' \
 )" ; \
done
wlx123456789012 2357:0109

Пояснения: для каждого интерфейса (для i in ... ; do ... ; done ) перечислите все пути интерфейсов Wi-Fi USB-ключей ( find /sys/class -name "wlx*" ) и для каждого пути получите и отобразите только интерфейс имя ( echo $i | grep -oE "[^/]+$" ) поэтому /sys/class/net/wlx123456789012 -> wlx123456789012, получить все свойства udev и отфильтровать эти свойства ( udevadm info $i | awk ... ) .

Процесс фильтрации:

  • создайте функцию, которая делит текущую запись ($0) на равный char ("=") и сохраняет результат в массиве "a" и возвращает второй элемент "a", поэтому значение идентификатора (функция get_val)

  • отфильтровать и сохранить значение ( /ID_VENDOR_ID/ ... и /ID_MODEL_ID/ ... )

  • наконец, распечатать сохраненные значения в правильном порядке поставщик: модель ( END { ... } )


И на основе @telcoM более независимый от системы и простой способ:

user@host:~$ for i in $( find /sys/class/net/ -type l -name "wlx*" ) ; do \
 echo "$( \
  echo $i | grep -oE "[^/]+$" \
 ) $( \
  cat $i/device/../idVendor \
 ):$( \
  cat $i/device/../idProduct \
 )" ; \
done
wlx123456789012 2357:0109

Пояснения: для каждого интерфейса (для i in ... ; do ... ; done ) перечислите все ссылки на интерфейсы Wi-Fi USB-ключей ( find /sys/class/net -type l -name "wlx*" ) и для каждой ссылки получить и отобразить только имя интерфейса ( echo $i | grep -oE "[^/]+$" ), поэтому /sys/class/net/wlx123456789012 -> wlx123456789012, и отобразить содержимое idVendor из связать родительскую папку и сделать то же самое с idProduct

1
Le Nain Jaune 3 Авг 2021 в 10:38

Я только что подключил беспроводной адаптер Ralink RT5370 к системе Debian 10.

По умолчанию оно отображается как сетевое устройство wlxc83a35c4a44b.

Вам нужно помнить, что /sys/class/* — это в основном поддерево каталогов, листья которого в основном являются символическими ссылками на ветвь /sys/devices/*.

# realpath /sys/class/net/wlxc83a35c4a44b
/sys/devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0/net/wlxc83a35c4a44b
# realpath /sys/class/net/wlxc83a35c4a44b/device
/sys/devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0

Таким образом, символическая ссылка device фактически работает внутри ветки /sys/devices/..., и между USB-контроллером и устройством есть один уровень (1-8) (в данном случае USB-концентраторы отсутствуют). Будет ли этот уровень содержать что-нибудь полезное?

# ls --format=commas /sys/devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0/..
1-8:1.0/, ep_00/, power/, authorized, avoid_reset_quirk, bcdDevice,
bConfigurationValue, bDeviceClass, bDeviceProtocol, bDeviceSubClass,
bmAttributes, bMaxPacketSize0, bMaxPower, bNumConfigurations, bNumInterfaces,
busnum, configuration, descriptors, dev, devnum, devpath, driver@,
firmware_node@, idProduct, idVendor, ltm_capable, manufacturer, maxchild, port@,
product, quirks, removable, remove, rx_lanes, serial, speed, subsystem@,
tx_lanes, uevent, urbnum, version

Есть idProduct и idVendor. Можем ли мы получить к ним доступ только по имени сетевого устройства?

# cat /sys/class/net/wlxc83a35c4a44b/device/../idProduct
5370
# cat /sys/class/net/wlxc83a35c4a44b/device/../idVendor
148f

Давайте проверим, что это правильное устройство:

# lsusb -d 148f:5370
Bus 001 Device 014: ID 148f:5370 Ralink Technology, Corp. RT5370 Wireless Adapter

Кажется правильным.

И это также работает без рута и с добавленным между ними USB-концентратором:

$ realpath /sys/class/net/wlxc83a35c4a44b/device
/sys/devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7.2/1-7.2:1.0
$ cat /sys/class/net/wlxc83a35c4a44b/device/../idVendor
148f
$ cat /sys/class/net/wlxc83a35c4a44b/device/../idProduct
5370
1
telcoM 2 Авг 2021 в 12:57
Спасибо ! Мне это решение очень нравится и кажется более универсальным, потому что, насколько я понимаю, не все Linux-системы основаны на udev. Цель моего сценария — быть как можно более «независимой от системы». Кроме того, я никогда не видел, чтобы родительская папка ссылки приводила к родительской папке цели ссылки.
 – 
Le Nain Jaune
2 Авг 2021 в 13:33
В таких оболочках, как bash, команда cd обрабатывает .. специально для удобства пользователя. На справочной странице bash говорится: "Если .. появляется в dir, он обрабатывается путем удаления непосредственно предшествующего компонента имени пути из dir, обратно в косая черта или начало dir." Это не как обрабатывают файловые системы: вы можете использовать cd -P для явного запроса с использованием фактической записи каталога .. или использовать set -P для создания cd ведут себя так по умолчанию. Таким образом, поведение, которого вы научились ожидать, на самом деле является исключением, а не правилом.
 – 
telcoM
2 Авг 2021 в 14:08
ОК Спасибо за эту тонкость.
 – 
Le Nain Jaune
2 Авг 2021 в 16:44