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'"

最初の4つの部分は、デバイスが接続されたときに生成されたイベントと正確に一致します。特に次のようになります。

  • SUBSYSTEM=="net"ネットワークデバイスの一致
  • ENV{ID_BUS}=="usb"USB経由で接続されているネットワークデバイスにのみ一致します。
  • ENV{ID_USB_DRIVER}=="rndis_host"RNDISホストデバイスドライバ(Android携帯電話のUSBテザリング用の標準ドライバ(WindowsおよびBlackberryも同様))を使用するUSB​​デバイスにのみ一致します。
  • ACTION=="add"ホットプラグイベントのみが一致します(したがって、デバイスが接続されている場合にのみ実行されますが、電話が接続されていないときにタスクを実行するために、「削除」タスクに一致する2番目の同様のルールを簡単に追加できます)。

最後のエントリは、ルール処理が完了したときに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

関連情報