lsusbによって返されたバス/デバイス番号に物理USBデバイスパスをマップします


9

接続されているUSBデバイスのタイトルを取得する必要があります。私はそれを行うことができますlsusb

udevは、ルールを記述するときにいくつかの置換を許可します。たとえば、$kernelデバイスの名前$devpathを取得したり、デバイスへのパスを取得したりすることができます。

しかし問題はそのlsusbような文字列を返すことです:

Bus 005 Device 032: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC

しかし、udevのdevpathは次のとおりです。

/devices/pci0000:00/0000:00:1d.0/usb5/5-2 

バス番号は同じ(5)ですが、番号が異なります。Device 032論理的な番号のように見え(デバイスを再接続すると、この番号が増加します)、2物理的なデバイス番号のようです。

そのため、udevは物理番号を返し、論理番号を取得する必要があります。次に、次のようにデータを取得できます。lsusb -D /dev/bus/usb/005/032

では、どうすれば032物理パスで論理デバイス番号を取得でき/devices/pci0000:00/0000:00:1d.0/usb5/5-2ますか?

回答:


5

まず、/sysによって返されるパスの前に付加する必要があるudevため、そのパスは次のようになります/sys/devices/pci0000:00/0000:00:1d.0/usb5/5-2。次に、このディレクトリに移動します。そこにいくつかのファイルがあります。他にも、busnumdevnumファイルがあり、これらの「論理」番号が含まれています。したがって、bashスクリプトでは、次のように取得できます。

devpath='/devices/pci0000:00/0000:00:1d.0/usb5/5-2'

busnum=$(cat "/sys/$devpath/busnum")
devnum=$(cat "/sys/$devpath/devnum")

# we might want to make busnum and devnum have leading zeros
# (say, "003" instead of "3", and "012" instead of "12")
busnum=$(printf %03d $busnum)
devnum=$(printf %03d $devnum)

# now, we can retrieve device data by   lsusb -D /dev/bus/usb/$busnum/$devnum

echo "busnum=$busnum, devnum=$devnum"

また、udevこれらbusnumdevnum直接返すことができることにも注意してください:では、それぞれRUN+="..."置換$attr{busnum}とを使用できます$attr{devnum}


1
udevvs. lsusbsys/devices/..vs.のさまざまな使い方に戸惑い、/dev/bus/usb/..あなたが知っているように思われるあなたの答えで判断すると:)多分あなたはこれらの2つの質問にいくつかの光を当てることができますか?askubuntu.com/questions/342061/power-on-off-usb-portsおよびaskubuntu.com/questions/498950/…–
nattyについてのナッツ

@nuttyaboutnatty、残念ながら私はあなたにあなたの問題の手がかりを与えることはできません(デバイスの電源を切ることについて)。私は最近、Linuxのことを学んでいるだけで、どんな種類のグルからも遠く離れています。/sys/devices/...vs についてはほとんどありません/dev/.../sysカーネルによって入力されます。これは実際のカーネルデバイス階層の表現です。Udevは、/sys階層を処理してデータを取り込む/dev/...(ルールを考慮に入れる)ユーザー空間デーモンです。したがって、udevは/devコンテンツに対して完全に責任があります。
Dmitry Frank

1

受け入れられた答えは本当に私をそれほど助けませんでした。最終的に、idProductとidVendorが存在するかどうかを調べることで方法を見つけました。これがシェルスクリプトです

#!/bin/bash
{ 
  cd /sys/bus/usb/devices
  for i in *; do 
    [ -e $i/idProduct ] && echo $(cat $i/idVendor $i/idProduct) $i
  done
}

ここに私が私のシステムで得るものがあります。

$ ./script
0424 2514 1-3
8087 0024 2-1
0a5c 21e6 2-1.4
8087 0024 4-1
1d6b 0002 usb1
1d6b 0002 usb2
1d6b 0003 usb3
1d6b 0002 usb4

$ lsusb
Bus 004 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 004 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 006: ID 0a5c:21e6 Broadcom Corp. BCM20702 Bluetooth 4.0 [ThinkPad]
Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 003: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

ここ0a5c:21e6では、たとえばBluetoothデバイスであるがにマッピングされて2-1.4いることがわかります。

さらに便利なように、これをシェル内の関数として定義できます。

$ cat >> ~/.bashrc << ENDL
gousb() {
  for i in /sys/bus/usb/devices/*; do 
    if [ -e \$i/idProduct ]; then
      if [ \$(cat \$i/idVendor):\$(cat \$i/idProduct) = \$1 ]; then 
        cd \$i
        return
      fi
    fi
  done

  echo "\$1 not found :-("
}
ENDL
$ source ~/.bashrc
$ gousb 0a5c:21e6
$ pwd 
/sys/bus/usb/devices/2-1.4
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.