Read USB Bus and Interface Details with usb-devices

A USB gadget shows up but its driver, speed or interfaces are a mystery: usb-devices prints exactly that from sysfs. The report covers device identity, configuration, active interfaces and endpoints, which is useful when a USB device is present but its driver or topology is unclear.

Allow about ten minutes. You need a shell and the usbutils package. The examples use usbutils 1:017-3build1, installed on this machine. The command is read-only and normally needs no elevated privileges. It does not reset a device, unload a driver or change a USB setting.

1. Confirm the installed command

Check which executable your shell will run, then record the package version:

$ command -v usb-devices
/usr/bin/usb-devices
$ dpkg-query -W -f='${Package} ${Version}\n' usbutils
usbutils 1:017-3build1

The command has no documented options. Its complete invocation is simply usb-devices. Do not add guessed flags copied from lsusb; the two tools are related, but their command lines are not interchangeable.

Checkpoint: If command -v prints nothing, stop here and install usbutils through your normal package-management process. Do not download a replacement script into a system directory.

2. Print the USB report

Run the command without sudo:

$ usb-devices

T:  Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=480  MxCh=12
D:  Ver= 2.00 Cls=09(hub  ) Sub=00 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=1d6b ProdID=0002 Rev=06.08
S:  Manufacturer=Linux 6.8.0-139-generic xhci-hcd
S:  Product=xHCI Host Controller
S:  SerialNumber=0000:00:14.0
C:  #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=0mA
I:  If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   4 Ivl=256ms

Your buses and values will differ. A report is built from blocks that each start with T:. Here, Bus=01 identifies the bus, Lev and Prnt describe its position in the USB tree, and Spd=480 records the bus speed in megabits per second. A root hub can appear even when nothing external is plugged in, so do not read one as a fault.

3. Read interfaces and endpoints correctly

An I: line describes an interface, not a second physical device. Its If# is the interface number, Alt is the alternate setting, #EPs is the endpoint count, and Driver is the driver attached to that interface. Class, subclass and protocol values help identify what the interface does.

An E: line describes an endpoint belonging to the interface above it. Ad=81(I) means address 81 with an input direction, while Atr=03(Int.) identifies an interrupt endpoint. Maximum packet size and polling interval follow.

The installed script deliberately reports active interfaces and their endpoints. It is not a byte-for-byte replacement for the kernel's usb/devices file: ordering and formatting can differ, and inactive interfaces are left out. Treat the output as a diagnostic report, not a stable machine-readable API.

Checkpoint: When investigating a device, find its P: line first, then read the C:, I: and E: lines in the same block. Do not assume the first block is the device you just plugged in.

4. Capture output for a comparison

USB topology changes as devices are connected and disconnected. Save a report to a file if you need to compare two moments:

$ usb-devices > usb-devices-before.txt
$ usb-devices > usb-devices-after.txt
$ diff -u usb-devices-before.txt usb-devices-after.txt

These commands write only to the current directory. Rename an existing file first if it matters, because > truncates whatever is already at that destination before the command runs. Use a new directory or filename rather than overwriting a previous capture.

For a quick, non-destructive check that the command produced data, use:

$ test -s usb-devices-after.txt && echo 'report is non-empty'
report is non-empty

There is nothing to undo in the USB system itself. To remove a capture later, delete that file only after checking you no longer need it; doing so has no effect on the USB devices it described.

5. Check a missing or failed report

The command walks USB entries below /sys/bus/usb/devices/usb*. Check the prerequisite first, without touching mounts or kernel settings:

$ test -d /sys/bus && echo '/sys/bus exists'
/sys/bus exists
$ test -d /sys/bus/usb/devices && echo 'USB sysfs directory exists'
USB sysfs directory exists
$ usb-devices > /tmp/usb-devices-check.txt
$ printf 'exit status: %s\n' "$?"
exit status: 0

The manpage specifies a non-zero exit status when sysfs is not mounted. If /sys/bus or the USB directory is missing, that is a kernel-interface problem, not evidence of a missing USB accessory. Do not respond by resetting hardware or changing service configuration.

Use elevated privileges only once your system administrator has established that the sysfs path exists but your account cannot read it. A typical diagnostic:

$ ls -ld /sys /sys/bus /sys/bus/usb /sys/bus/usb/devices
$ usb-devices

Keep the second command unprivileged if it succeeds. Running it through sudo will not make an unmounted sysfs appear, and it can hide the real ownership or mount problem.

6. Keep the report in context

A successful run means the script could walk the sysfs tree and print what it found. It does not prove every connected device is healthy, that a driver is functioning correctly, or that a device will accept I/O. Missing string fields are not automatically errors, and a USB hub entry is normal, not a symptom.

When a device seems absent, compare the report before and after reconnecting it, then check the kernel log with your distribution's usual tools. Avoid repeatedly unplugging storage or other mounted devices while you investigate: that can interrupt writes and cause data loss. Unmount storage through the normal desktop or system procedure before disconnecting it.

For scripts, check the exit status and keep the raw report for a human to inspect rather than parsing it live. The field layout resembles the kernel's USB device listing, but the manpage explicitly warns that sorting and formatting can differ. Parsing labels such as Vendor= is safer than relying on fixed column positions, but test against the usbutils version actually deployed on your systems.

Done means