Uname: Linux 50-6-4-53.bluehost.com 5.14.0-611.41.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Mar 19 03:50:11 EDT 2026 x86_64
User: 1011 (dccreditrepairto)
Group: 1010 (dccreditrepairto)
Disabled functions: NONE
Safe mode: On[ PHPinfo ]
//bin      ( Reset | Go to )
File Name: lsusb.py
#!/usr/bin/python3
# SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
#
# lsusb-017.py
#
# Displays your USB devices in reasonable form.
#
# Copyright (c) 2009 Kurt Garloff <[email protected]>
# Copyright (c) 2013,2018 Kurt Garloff <[email protected]>
#
# Usage: See usage()

# Py2 compat
from __future__ import print_function
import getopt
import os
import re
import sys

HUB_ICLASS = 0x09

# Global options
showint = False
showhubint = False
noemptyhub = False
nohub = False
showeps = False
showwakeup = False

prefix = "/sys/bus/usb/devices/"
usbids = [
    "/usr/share/hwdata/usb.ids",
    "/usr/share/hwdata/usb.ids",
    "/usr/share/usb.ids",
]
cols = ("", "", "", "", "", "")

norm    = "\033[0;0m"
bold    = "\033[0;1m"
red    = "\033[0;31m"
green    = "\033[0;32m"
amber    = "\033[0;33m"
blue    = "\033[0;34m"

usbvendors = {}
usbproducts = {}
usbclasses = {}

def colorize(num, text):
    return cols[num] + str(text) + cols[0]

def ishexdigit(str):
    "return True if all digits are valid hex digits"
    for dg in str:
        if not dg.isdigit() and not dg in 'abcdef':
            return False
    return True

def open_read_ign(fn):
    try:
        return open(fn, 'r', errors='ignore')
    except:
        return open(fn, 'r')

def myenum(*args):
    enums = dict(zip(args, range(len(args))))
    return type('MyEnum', (), enums)

def parse_usb_ids():
    "Parse /usr/share/usb.ids and fill usbvendors, usbproducts, usbclasses"
    vid = 0
    did = 0
    modes = myenum('Vendor', 'Class', 'Misc')
    mode = modes.Vendor
    strg = ""
    cstrg = ""
    for unm in usbids:
        if os.path.exists(unm):
            break
    for ln in open_read_ign(unm).readlines():
        if ln[0] == '#':
            continue
        ln = ln.rstrip('\n')
        if len(ln) == 0:
            continue
        if ishexdigit(ln[0:4]):
            mode = modes.Vendor
            vid = int(ln[:4], 16)
            usbvendors[vid] = ln[6:]
            continue
        if ln[0] == '\t' and ishexdigit(ln[1:3]):
            # usb.ids has a device id of 01xy, sigh
            if ln[3:5] == "xy":
                did = int(ln[1:3], 16)*256
            else:
                did = int(ln[1:5], 16)
            # USB devices
            if mode == modes.Vendor:
                usbproducts[vid, did] = ln[7:]
                continue
            elif mode == modes.Class:
                nm = ln[5:]
                if nm != "Unused":
                    strg = cstrg + ":" + nm
                else:
                    strg = cstrg + ":"
                usbclasses[vid, did, -1] = strg
                continue
        if ln[0] == 'C':
            mode = modes.Class
            cid = int(ln[2:4], 16)
            cstrg = ln[6:]
            usbclasses[cid, -1, -1] = cstrg
            continue
        if mode == modes.Class and ln[0] == '\t' and ln[1] == '\t' and ishexdigit(ln[2:4]):
            prid = int(ln[2:4], 16)
            usbclasses[cid, did, prid] = ln[6:]
            continue
        mode = modes.Misc
    usbclasses[0xFF, 0xFF, 0xFF] = "Vendor Specific"

def find_usb_prod(vid, pid):
    "Return device name from USB Vendor:Product list"
    strg = ""
    vendor = usbvendors.get(vid)
    if vendor:
        strg = str(vendor)
    else:
        return ""
    product = usbproducts.get((vid, pid))
    if product:
        return strg + " " + str(product)
    return strg

def find_usb_class(cid, sid, pid):
    "Return USB protocol from usbclasses list"
    lnlst = len(usbclasses)
    cls = usbclasses.get((cid, sid, pid)) \
        or usbclasses.get((cid, sid, -1)) \
        or usbclasses.get((cid, -1, -1))
    if cls:
        return str(cls)
    return ""


devlst = [
    'host',            # usb-storage
    'video4linux/video',    # uvcvideo et al.
    'sound/card',        # snd-usb-audio
    'net/',            # cdc_ether, ...
    'input/input',        # usbhid
    'usb:hiddev',        # usb hid
    'bluetooth/hci',    # btusb
    'ttyUSB',        # btusb
    'tty/',            # cdc_acm
    'usb:lp',        # usblp
    #'usb/lp',        # usblp
    'usb/',            # hiddev, usblp
    #'usbhid',        # hidraw
]

def find_storage(hostno):
    "Return SCSI block dev names for host"
    res = ""
    for ent in os.listdir("/sys/class/scsi_device/"):
        (host, bus, tgt, lun) = ent.split(":")
        if host == hostno:
            try:
                for ent2 in os.listdir("/sys/class/scsi_device/%s/device/block" % ent):
                    res += ent2 + " "
            except:
                pass
    return res

def add_drv(path, drvnm):
    res = ""
    try:
        for e2 in os.listdir(path+"/"+drvnm):
            if e2[0:len(drvnm)] == drvnm:
                res += e2 + " "
        try:
            if res:
                res += "(" + os.path.basename(os.readlink(path+"/driver")) + ") "
        except:
            pass
    except:
        pass
    return res

def find_dev(driver, usbname):
    "Return pseudo devname that's driven by driver"
    res = ""
    for nm in devlst:
        dirnm = prefix + usbname
        prep = ""
        idx = nm.find('/')
        if idx != -1:
            prep = nm[:idx+1]
            dirnm += "/" + nm[:idx]
            nm = nm[idx+1:]
        ln = len(nm)
        try:
            for ent in os.listdir(dirnm):
                if ent[:ln] == nm:
                    res += prep+ent+" "
                    if nm == "host":
                        res += "(" + find_storage(ent[ln:])[:-1] + ")"
        except:
            pass
    if driver == "usbhid":
        rg = re.compile(r'[0-9A-F]{4}:[0-9A-F]{4}:[0-9A-F]{4}\.[0-9A-F]{4}')
        for ent in os.listdir(prefix + usbname):
            m = rg.match(ent)
            if m:
                res += add_drv(prefix+usbname+"/"+ent, "hidraw")
                add = add_drv(prefix+usbname+"/"+ent, "input")
                if add:
                    res += add
                else:
                    for ent2 in os.listdir(prefix+usbname+"/"+ent):
                        m = rg.match(ent2)
                        if m:
                            res += add_drv(prefix+usbname+"/"+ent+"/"+ent2, "input")
    return res


class UsbObject:
    def read_attr(self, name):
        path = prefix + self.path + "/" + name
        return open(path).readline().strip()

    def read_link(self, name):
        path = prefix + self.path + "/" + name
        return os.path.basename(os.readlink(path))

class UsbEndpoint(UsbObject):
    "Container for USB endpoint info"
    def __init__(self, parent, fname, level):
        self.parent = parent
        self.level = level
        self.fname = fname
        self.path = ""
        self.epaddr = 0
        self.len = 0
        self.ival = ""
        self.type = ""
        self.attr = 0
        self.max = 0
        if self.fname:
            self.read(self.fname)

    def read(self, fname):
        self.fname = fname
        self.path = self.parent.path + "/" + fname
        self.epaddr = int(self.read_attr("bEndpointAddress"), 16)
        ival = int(self.read_attr("bInterval"), 16)
        if ival:
            self.ival = " (%s)" % self.read_attr("interval")
        self.len = int(self.read_attr("bLength"), 16)
        self.type = self.read_attr("type")
        self.attr = int(self.read_attr("bmAttributes"), 16)
        self.max = int(self.read_attr("wMaxPacketSize"), 16)

    def __repr__(self):
        return "<UsbEndpoint[%r]>" % self.fname

    def __str__(self):
        indent = "  " * self.level
        #name = "%s/ep_%02X" % (self.parent.fname, self.epaddr)
        name = ""
        body = "(EP) %02x: %s%s attr %02x len %02x max %03x" % \
            (self.epaddr, self.type, self.ival, self.attr, self.len, self.max)
        body = colorize(5, body)
        return "%-17s %s\n" % (indent + name, indent + body)


class UsbInterface(UsbObject):
    "Container for USB interface info"
    def __init__(self, parent, fname, level=1):
        self.parent = parent
        self.level = level
        self.fname = fname
        self.path = ""
        self.iclass = 0
        self.isclass = 0
        self.iproto = 0
        self.noep = 0
        self.driver = ""
        self.devname = ""
        self.protoname = ""
        self.eps = []
        if self.fname:
            self.read(self.fname)

    def read(self, fname):
        self.fname = fname
        self.path = self.parent.path + "/" + fname
        self.iclass = int(self.read_attr("bInterfaceClass"),16)
        self.isclass = int(self.read_attr("bInterfaceSubClass"),16)
        self.iproto = int(self.read_attr("bInterfaceProtocol"),16)
        self.noep = int(self.read_attr("bNumEndpoints"))
        try:
            self.driver = self.read_link("driver")
            self.devname = find_dev(self.driver, self.path)
        except:
            pass
        self.protoname = find_usb_class(self.iclass, self.isclass, self.iproto)
        if showeps:
            for dirent in os.listdir(prefix + self.path):
                if dirent.startswith("ep_"):
                    ep = UsbEndpoint(self, dirent, self.level+1)
                    self.eps.append(ep)

    def __repr__(self):
        return "<UsbInterface[%r]>" % self.fname

    def __str__(self):
        indent = "  " * self.level
        name = self.fname
        plural = (" " if self.noep == 1 else "s")
        body = "(IF) %02x:%02x:%02x %iEP%s (%s) %s %s" % \
            (self.iclass, self.isclass, self.iproto, self.noep, plural,
             self.protoname, colorize(3, self.driver), colorize(4, self.devname))
        strg = "%-17s %s\n" % (indent + name, indent + body)
        if showeps and self.eps:
            for ep in self.eps:
                strg += str(ep)
        return strg

class UsbDevice(UsbObject):
    "Container for USB device info"
    def __init__(self, parent, fname, level=0):
        self.parent = parent
        self.level = level
        self.fname = fname
        self.path = ""
        self.iclass = 0
        self.isclass = 0
        self.iproto = 0
        self.vid = 0
        self.pid = 0
        self.name = ""
        self.usbver = ""
        self.speed = ""
        self.maxpower = ""
        self.wakeup = ""
        self.noports = 0
        self.nointerfaces = 0
        self.driver = ""
        self.devname = ""
        self.interfaces = []
        self.children = []
        if self.fname:
            self.read(self.fname)
            self.readchildren()

    def read(self, fname):
        self.fname = fname
        self.path = fname
        self.iclass = int(self.read_attr("bDeviceClass"), 16)
        self.isclass = int(self.read_attr("bDeviceSubClass"), 16)
        self.iproto = int(self.read_attr("bDeviceProtocol"), 16)
        self.vid = int(self.read_attr("idVendor"), 16)
        self.pid = int(self.read_attr("idProduct"), 16)
        try:
            self.name = self.read_attr("manufacturer") + " " \
                  + self.read_attr("product")
        except:
            pass
        if self.name:
            mch = re.match(r"Linux [^ ]* (.hci[_-]hcd) .HCI Host Controller", self.name)
            if mch:
                self.name = mch.group(1)
        if not self.name:
            self.name = find_usb_prod(self.vid, self.pid)
        # Some USB Card readers have a better name then Generic ...
        if self.name.startswith("Generic"):
            oldnm = self.name
            self.name = find_usb_prod(self.vid, self.pid)
            if not self.name:
                self.name = oldnm
        try:
            ser = self.read_attr("serial")
            # Some USB devs report "serial" as serial no. suppress
            if (ser and ser != "serial"):
                self.name += " " + ser
        except:
            pass
        self.usbver = self.read_attr("version")
        self.speed = self.read_attr("speed")
        self.maxpower = self.read_attr("bMaxPower")
        self.noports = int(self.read_attr("maxchild"))
        try:
            self.nointerfaces = int(self.read_attr("bNumInterfaces"))
        except:
            self.nointerfaces = 0
        try:
            self.driver = self.read_link("driver")
            self.devname = find_dev(self.driver, self.path)
        except:
            pass
        if showwakeup:
            try:
                self.wakeup = self.read_attr('power/wakeup')
            except:
                self.wakeup = "unsupported"

    def readchildren(self):
        if self.fname[0:3] == "usb":
            fname = self.fname[3:]
        else:
            fname = self.fname
        for dirent in os.listdir(prefix + self.fname):
            if not dirent[0:1].isdigit():
                continue
            if os.access(prefix + dirent + "/bInterfaceClass", os.R_OK):
                iface = UsbInterface(self, dirent, self.level+1)
                self.interfaces.append(iface)
            else:
                usbdev = UsbDevice(self, dirent, self.level+1)
                self.children.append(usbdev)
        usbsortkey = lambda obj: [int(x) for x in re.split(r"[-:.]", obj.fname)]
        self.interfaces.sort(key=usbsortkey)
        self.children.sort(key=usbsortkey)

    def __repr__(self):
        return "<UsbDevice[%r]>" % self.fname

    def __str__(self):
        is_hub = (self.iclass == HUB_ICLASS)
        if is_hub:
            if noemptyhub and len(self.children) == 0:
                return ""
        strg = ""
        if not (nohub and is_hub):
            indent = "  " * self.level
            name = self.fname
            plural = (" " if self.nointerfaces == 1 else "s")
            body = "%s %02x %iIF%s [USB %s, %5s Mbps, %5s%s] (%s)%s" % \
                (colorize(1, "%04x:%04x" % (self.vid, self.pid)),
                 self.iclass, self.nointerfaces, plural,
                 self.usbver.strip(), self.speed, self.maxpower,
                 ("" if self.wakeup == "" else (",  power wakeup: %s" % self.wakeup)),
                 colorize(2 if is_hub else 1, self.name),
                 colorize(2, " hub") if is_hub else "")
            strg = "%-17s %s\n" % (indent + name, indent + body)
            if not (is_hub and not showhubint):
                if showeps:
                    ep = UsbEndpoint(self, "ep_00", self.level+1)
                    strg += str(ep)
                if showint:    
                    for iface in self.interfaces:
                        strg += str(iface)
        for child in self.children:
            strg += str(child)
        return strg


def usage():
    "Displays usage information"
    print("Usage: lsusb.py [options]")
    print()
    print("Options:")
    print("  -h, --help            display this help")
    print("  -i, --interfaces      display interface information")
    print("  -I, --hub-interfaces  display interface information, even for hubs")
    print("  -u, --hide-empty-hubs suppress empty hubs")
    print("  -U, --hide-hubs       suppress all hubs")
    print("  -c, --color           use colors")
    print("  -C, --no-color        disable colors")
    print("  -e, --endpoints       display endpoint info")
    print("  -f FILE, --usbids-path FILE")
    print("                        override filename for /usr/share/usb.ids")
    print("  -w, --wakeup          display power wakeup setting")
    print()
    print("Use lsusb.py -ciu to get a nice overview of your USB devices.")

def read_usb():
    "Read toplevel USB entries and print"
    root_hubs = []
    for dirent in os.listdir(prefix):
        if not dirent[0:3] == "usb":
            continue
        usbdev = UsbDevice(None, dirent, 0)
        root_hubs.append(usbdev)
    root_hubs.sort(key=lambda x: int(x.fname[3:]))
    for usbdev in root_hubs:
        print(usbdev, end="")

def main(argv):
    "main entry point"
    global showint, showhubint, noemptyhub, nohub
    global cols, usbids, showeps, showwakeup
    usecols = None

    long_options = [
        "help",
        "interfaces",
        "hub-interfaces",
        "hide-empty-hubs",
        "hide-hubs",
        "color",
        "no-color",
        "usbids-path=",
        "endpoints",
        "wakeup",
    ]

    try:
        (optlist, args) = getopt.gnu_getopt(argv[1:], "hiIuUwcCef:", long_options)
    except getopt.GetoptError as exc:
        print("Error:", exc, file=sys.stderr)
        sys.exit(2)
    for opt in optlist:
        if opt[0] in {"-h", "--help"}:
            usage()
            sys.exit(0)
        elif opt[0] in {"-i", "--interfaces"}:
            showint = True
        elif opt[0] in {"-I", "--hub-interfaces"}:
            showint = True
            showhubint = True
        elif opt[0] in {"-u", "--hide-empty-hubs"}:
            noemptyhub = True
        elif opt[0] in {"-U", "--hide-hubs"}:
            noemptyhub = True
            nohub = True
        elif opt[0] in {"-c", "--color"}:
            usecols = True
        elif opt[0] in {"-C", "--no-color"}:
            usecols = False
        elif opt[0] in {"-f", "--usbids-path"}:
            usbids = [opt[1]]
        elif opt[0] in {"-e", "--endpoints"}:
            showeps = True
        elif opt[0] in {"-w", "--wakeup"}:
            showwakeup = True
    if len(args) > 0:
        print("Error: excess args %s ..." % args[0], file=sys.stderr)
        sys.exit(2)

    if usecols is None:
        usecols = sys.stdout.isatty() and os.environ.get("TERM", "dumb") != "dumb"

    if usecols:
        cols = (norm, bold, red, green, amber, blue)

    if usbids[0]:
        try:
            parse_usb_ids()
        except:
            print(" WARNING: Failure to read usb.ids", file=sys.stderr)
            #print(sys.exc_info(), file=sys.stderr)
    read_usb()

# Entry point
if __name__ == "__main__":
    main(sys.argv)


All system for education purposes only. For more tools: Telegram @jackleet

Mr.X Private Shell

Logo
-
New File | New Folder
Command
SQL