Как определить, когда Android-устройство подключено через USB-модем и получить его имя интерфейса?

Я унаследовал сценарий bash, который должен определить имя интерфейса любого Android-устройства, подключенного через USB-модем, а затем записывает это имя интерфейса в другую переменную. Вот существующий код (упрощенный).

if [ -s /sys/class/net/enp0s20f0u3/operstate ]; then /usr/bin/echo "enp0s20f0u3" > /var/tmp/myfile elif [ -s /sys/class/net/enp0s20f0u5/operstate ]; then /usr/bin/echo "enp0s20f0u5" > /var/tmp/myfile elif [ -s /sys/class/net/enp6s0u1/operstate ]; then /usr/bin/echo "enp6s0u1" > /var/tmp/myfile elif [ -s /sys/class/net/enp0s20f0u4/operstate ]; then /usr/bin/echo "enp0s20f0u4" > /var/tmp/myfile elif [ -s /sys/class/net/enp0s20f0u6/operstate ]; then /usr/bin/echo "enp0s20f0u6" > /var/tmp/myfile elif [ -s /sys/class/net/enp0s20f0u10/operstate ]; then /usr/bin/echo "enp0s20f0u10" > /var/tmp/myfile 

Если для будущего устройства Android задано другое имя интерфейса, код должен быть изменен вручную после того, как мы обнаружим, что сценарий не работает. Очевидно, что это очень плохая реализация.

Каков лучший способ достичь тех же результатов?

ИЗМЕНИТЬ 1:

То, что я действительно имею в виду, – как этот код может быть реорганизован так, чтобы каждое имя интерфейса не требовалось жестко закодировать?

2 Solutions collect form web for “Как определить, когда Android-устройство подключено через USB-модем и получить его имя интерфейса?”

В идеальной ситуации? Перепишите это как правило udev, чтобы оно автоматически включалось при подключении. Он должен быть оценен после других правил, так что любое переименование интерфейса уже произошло к моменту его оценки ( /etc/udev/rules.d/99-x-local.conf , вероятно, это место, чтобы положить его), но основное правило должно выглядеть примерно так:

 SUBSYSTEM=="net", ENV{ID_BUS}=="usb", ENV{ID_USB_DRIVER}=="rndis_host", ACTION=="add", RUN{program}+="/bin/sh -c 'echo $env{INTERFACE} > /var/tmp/myfile'" 

Первые четыре части соответствуют точному событию, генерируемому при подключении устройства, а именно:

  • SUBSYSTEM=="net" соответствует сетевым устройствам
  • ENV{ID_BUS}=="usb" соответствует только тем сетевым устройствам, которые подключены через USB.
  • ENV{ID_USB_DRIVER}=="rndis_host" соответствует только USB-устройствам, использующим драйвер хост-устройства RNDIS (стандартный, используемый телефонами Android (и, я думаю, Windows и Blackberry) для USB-модема.
  • ACTION=="add" совпадения только в событиях hotplug (так что это запускается только при подключении устройства, хотя вы можете так же легко добавить второе аналогичное соответствие правилу в действие «удалить», чтобы что-то сделать, когда телефон отключился ).

Последний элемент добавляет команду в очередь вещей, которые udev будет вызывать, когда обработка правил будет выполнена. В этом случае он добавляет вызов оболочки, который выведет имя интерфейса в нужное место (сам udev заменит $env{INTERFACE} для фактического имени интерфейса).

Я не могу гарантировать, что это будет работать во всех случаях, но, по крайней мере, это работает для моего Nexus 6P и теоретически работает для большинства телефонов Android.

Если в заказе нет знака, вы можете просто просмотреть все каталоги в каталоге /sys/class/net/ до тех пор, пока не найдете ту, которая находится вверху, и не является устройством loopback:

 for interface in /sys/class/net/* do name=${interface##*/} # just the final directory state=$(<$interface/operstate) # read the file [ "$name" = lo ] && continue # if lo continue to next [ "$state" = up ] || continue # if not up continue to next echo $name >/var/tmp/myfile break # stop done 
Linux и Unix - лучшая ОС в мире.