
Я работаю над пользовательскими скриптами Bash для массового копирования USB-флеш-памяти и массового тестирования (с использованием f3
).
Интересно, можно ли определить, к какому USB-порту подключена флешка?
У меня есть USB-хабы с пронумерованными портами. Если бы у них были какие-то статические адреса, которые я мог бы идентифицировать и знать, подключено ли к ним что-то или нет, и что это такое (по сути: какой файл /dev/sd* соответствует этому USB-порту), я мог бы сделать так, чтобы пользователям было намного проще узнать, что происходит, и позволить им удалять плохие диски на ранней стадии процесса, не дожидаясь, пока вся партия будет обработана, а затем попытаться отсортировать плохие диски от хороших (вот как я это делаю сейчас).
Я попытался поискать, но ничего из того, что я нашел, не соответствовало тому, чего я хотел добиться, поэтому я решил напрямую обратиться за помощью в этом контексте.
Сейчас я идентифицирую диски по именам узлов /dev/sd*, а пользователи понятия не имеют, что это такое. Если бы я мог сопоставить их с портами USB в концентраторе, я мог бы представить информацию на основе портов USB, и пользователи могли бы узнать, что к порту 5 подключен неисправный диск, и они могли бы удалить его, не мешая остальному процессу.
Затем я мог бы даже прекратить делать это партиями и заставить все порты работать одновременно в цикле, пользователь мог бы постоянно подключать и отключать диски, отслеживая, что есть что, по номерам портов HUB, это могло бы значительно ускорить рабочий процесс.
Итак, основной вопрос: как мне идентифицировать USB-порты и USB-флеш-память, подключенную к этим портам?
решение1
Вы можете использовать udevadm
, чтобы получитьпуть к устройствунекоторого устройства. Это делается путем проверки символических ссылок в /sys/
, так что вы также можете сделать это вручную (но проще использовать udevadm
).
Например, USB-накопитель, подключенный к внешнему USB-концентратору моей системы, производит
$ udevadm info -q path -n /dev/sdh
/devices/pci0000:00/0000:00:1d.0/usb3/3-1/3-1.1/3-1.1.3/3-1.1.3.2/3-1.1.3.2:1.0/host7/target7:0:0/7:0:0:0/block/sdh
Как можно увидеть, сравнивая с деревом USB,
$ lsusb -t
/: Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 5000M
/: Bus 03.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/2p, 480M
|__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/8p, 480M
|__ Port 1: Dev 26, If 0, Class=Hub, Driver=hub/4p, 480M
|__ Port 3: Dev 29, If 0, Class=Hub, Driver=hub/4p, 480M
|__ Port 2: Dev 31, If 0, Class=Mass Storage, Driver=usb-storage, 480M
|__ Port 4: Dev 30, If 0, Class=Mass Storage, Driver=usb-storage, 480M
...
часть 3-1.1.3.2
пути говорит, что на шине 3 он проходит через порт 1 (на южном мосту), снова порт 1 (на материнской плате), порт 3 (все еще на материнской плате), а затем на порт 2 внешнего USB-концентратора. Порт 4 этого концентратора используется для устройства чтения SD-карт.
Поэтому в зависимости от того, как подключен ваш USB-концентратор, вам нужно сделать что-то похожее и извлечь последний интересующий вас порт.
решение2
Это альтернатива принятому решению, когда вы не знаете имени устройства, чтобы предоставить его команде (которая расскажет вам об устройстве).
ДОвставив USB-флешку, выполните:
udevadm monitor
После того, как флешка вставлена, она выдаст подробные сообщения Kernel и Udev, а в последней строке сообщит нам, как хост видит USB-флешку:
решение3
Похоже, /dev/disk/by-path
содержит символические ссылки на /dev/sd*
узлы и может быть использован для точного определения этого.
Выдача file /dev/disk/by-path/*
команды выводит список всех /dev/sd*
узлов и их физических адресов. Я должен быть в состоянии выполнить grep довольно легко.