USB 테더링을 통해 Android 기기가 연결된 시기를 감지하고 인터페이스 이름을 가져오는 방법은 무엇입니까?

USB 테더링을 통해 Android 기기가 연결된 시기를 감지하고 인터페이스 이름을 가져오는 방법은 무엇입니까?

USB 테더링을 통해 연결된 Android 장치의 인터페이스 이름을 감지한 다음 해당 인터페이스 이름을 다른 변수에 쓰는 bash 스크립트를 상속했습니다. 다음은 기존 코드(간소화)입니다.

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:

내 말은, 각 인터페이스 이름을 하드코딩할 필요가 없도록 이 코드를 어떻게 리팩터링할 수 있느냐는 것입니다.

답변1

이상적인 상황에서? 연결 시 자동으로 실행되도록 이를 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"RNDIS 호스트 장치 드라이버(Android 휴대폰의 USB 테더링용 표준 드라이버(Windows 및 Blackberry도 마찬가지))를 사용하는 USB 장치에만 일치합니다.
  • ACTION=="add"핫플러그 이벤트만 일치합니다(따라서 장치가 연결되어 있을 때만 실행됩니다. 단, 전화기가 연결되어 있지 않을 때 작업을 수행하기 위해 "제거" 작업에 일치하는 두 번째 유사한 규칙을 쉽게 추가할 수 있습니다).

마지막 항목은 규칙 처리가 완료되면 udev가 호출할 트랜잭션 대기열에 명령을 추가합니다. 이 경우 필요한 위치에 인터페이스 이름을 쓰는 쉘 호출을 추가합니다(udev 자체가 $env{INTERFACE}실제 인터페이스 이름을 대체합니다).

이것이 모든 경우에 작동할 것이라고 보장할 수는 없지만 적어도 내 Nexus 6P에서는 작동하는 것 같고 이론적으로는 대부분의 Android 휴대전화에서도 작동할 것입니다.

답변2

순서가 맞지 않으면 /sys/class/net/시작되었지만 루프백 장치가 아닌 디렉터리를 찾을 때까지 모든 디렉터리를 반복할 수 있습니다.

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

관련 정보