Colleghi una chiavetta e non compare. Una stampante viene riconosciuta solo a volte. Una tastiera smette di rispondere dopo un riavvio. Prima di cercare il driver o il cavo guasto, la domanda è sempre la stessa: il sistema vede la periferica? lsusb risponde, ed è il parente di lspci per le porte USB.
Cos'è
lsusb (list USB) fa parte del pacchetto usbutils (su Debian e Ubuntu: sudo apt install usbutils, vedi l'articolo su apt). Come lspci per il bus PCI e lsmod per i moduli, non cambia niente: legge le informazioni che il kernel (vedi l'articolo su uname) ha raccolto sui dispositivi USB collegati e le mostra con i nomi del costruttore e del modello, presi da un archivio di identificativi.
Cosa fa
Elenca tutti i dispositivi USB presenti: le periferiche (chiavette, tastiere, mouse, stampanti, telefoni, adattatori di rete) e anche gli hub e i root hub, le prese virtuali create dal controller USB della macchina. Con le opzioni mostra la struttura ad albero, gli identificativi e il dettaglio completo dei descrittori.
Come si usa
$ lsusb [opzioni]Una precisazione importante sulle prove. La macchina virtuale che uso per verificare i comandi non ha nessun controller USB: non esiste neppure la cartella /sys/bus/usb. Quindi tutti gli output di questo articolo con dispositivi sono illustrativi, scritti secondo il formato del programma, con i nomi presi dall'archivio vero (li ho letti dal database di usb.ids). Quello che ho potuto verificare davvero è il comportamento senza USB, l'elenco delle opzioni di lsusb 017 e un controllo con uno script. Gli esempi usano web01, il server degli articoli precedenti, ma gli stessi comandi valgono su qualsiasi macchina, per esempio un portatile.
Esempio 1: l'elenco dei dispositivi
$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 004: ID 0781:5581 SanDisk Corp. Ultra
Bus 001 Device 003: ID 046d:c31c Logitech, Inc. Keyboard K120
Bus 001 Device 002: ID 05e3:0608 Genesys Logic, Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hubOgni riga è un dispositivo: Bus è il bus USB a cui è collegato (ogni controller ne ha uno), Device il numero assegnato al momento del collegamento (cambia se lo si scollega e lo si ricollega), poi l'ID nella forma costruttore:modello (due codici esadecimali di quattro cifre) e infine i nomi. Le righe root hub sono i controller della macchina: ce n'è almeno una per ogni bus (2.0 e 3.0 indicano la velocità dello standard), e non sono periferiche vere. Il costruttore 1d6b (Linux Foundation) è quello di questi hub virtuali. L'elenco è illustrativo, ma i nomi e gli ID sono quelli veri dell'archivio.
Se non c'è alcun controller USB, come nella mia macchina di prova, lsusb non stampa niente e termina con codice 1; questo l'ho verificato. Conviene saperlo: un elenco vuoto non vuol dire "nessuna periferica" ma, in una macchina virtuale, spesso "nessun controller USB assegnato alla macchina".
Esempio 2: l'albero dei collegamenti
$ lsusb -t
/: Bus 002.Port 001: Dev 001, Class=root_hub, Driver=xhci_hcd/2p, 10000M
/: Bus 001.Port 001: Dev 001, Class=root_hub, Driver=xhci_hcd/4p, 480M
|__ Port 002: Dev 002, If 0, Class=Hub, Driver=hub/4p, 480M
|__ Port 001: Dev 003, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M
|__ Port 002: Dev 004, If 0, Class=Mass Storage, Driver=usb-storage, 480MCon -t (tree) i dispositivi sono disposti ad albero: dalla radice (il controller) agli hub, alle periferiche. Per ognuno si vedono la porta, il numero del dispositivo, la classe (Mass Storage per le chiavette e i dischi, Human Interface Device per tastiere e mouse, Hub, Printer, Wireless...), il driver in uso (qui usb-storage e usbhid) e la velocità: 1.5M (USB 1.0), 12M, 480M (USB 2.0), 5000M e 10000M (USB 3). Conviene guardare la velocità quando un disco esterno è lento: spesso è collegato a una porta più lenta, o con un cavo che non regge lo standard più veloce, e compare 480M invece di 5000M. In lsusb -t manca il nome commerciale, solo la classe: per quello serve l'elenco normale. Anche questo blocco è illustrativo. Nel sandbox lsusb -t risponde /sys/bus/usb/devices: No such file or directory (vero, e dimostra da dove legge: la cartella /sys/bus/usb/devices).
Esempio 3: cercare una periferica
$ lsusb | grep -i sandisk
Bus 001 Device 004: ID 0781:5581 SanDisk Corp. Ultra
$ lsusb -d 0781:
Bus 001 Device 004: ID 0781:5581 SanDisk Corp. Ultra
$ lsusb -d 0781:5581
Bus 001 Device 004: ID 0781:5581 SanDisk Corp. Ultra
$ lsusb -s 1:4
Bus 001 Device 004: ID 0781:5581 SanDisk Corp. Ultra
$ lsusb -s 001:004 -v | grep -E 'idVendor|idProduct|iProduct'Per cercare un dispositivo per nome si usa grep -i (vedi l'articolo su grep). Le opzioni di lsusb permettono invece di filtrare in modo preciso: -d (device) per costruttore:modello (anche solo il costruttore, come in -d 0781:, con i due punti finali), -s (show) per bus:numero (in decimale). L'ultima riga estrae solo alcuni campi dall'output dettagliato (esempio 4). L'elenco delle opzioni è quello di lsusb -h (versione 017), che ho letto davvero.
Esempio 4: i dettagli di un dispositivo
$ sudo lsusb -v -d 0781:5581 | head -n 14
Bus 001 Device 004: ID 0781:5581 SanDisk Corp. Ultra
Negotiated speed: High Speed (480Mbps)
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.10
bDeviceClass 0
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x0781 SanDisk Corp.
idProduct 0x5581 Ultra
bcdDevice 1.00
iManufacturer 1 SanDisk
iProduct 2 UltraCon -v (verbose) si ottiene il descrittore completo: tutto quello che il dispositivo dichiara di sé. È molto lungo, per questo conviene head o grep. I campi più utili: bcdUSB (la versione dello standard USB supportata), idVendor e idProduct, iManufacturer, iProduct e iSerial (i nomi e il numero di serie), e MaxPower, più in basso, il consumo dichiarato in milliampere. Serve sudo per alcuni dettagli (senza, compaiono errori di tipo Couldn't open device): le informazioni di base arrivano comunque. Il blocco è illustrativo (il formato è quello di lsusb).
Esempio 5: capire cosa succede al collegamento
$ sudo dmesg -w -T
[Sat Nov 7 09:12:40 2026] usb 1-2: new high-speed USB device number 4 using xhci_hcd
[Sat Nov 7 09:12:40 2026] usb 1-2: New USB device found, idVendor=0781, idProduct=5581
[Sat Nov 7 09:12:40 2026] usb 1-2: Product: Ultra
[Sat Nov 7 09:12:41 2026] sd 6:0:0:0: [sdb] Attached SCSI removable disk
$ lsblk -o NAME,SIZE,TRAN,MODEL /dev/sdb
NAME SIZE TRAN MODEL
sdb 29.8G usb UltraUn metodo pratico per diagnosticare è tenere aperto dmesg -w (follow: vedi l'articolo su dmesg) e collegare la periferica: il kernel scrive subito se l'ha riconosciuta, a che velocità, con quale numero (usb 1-2 è bus 1, porta 2) e, per un disco, il nome del nuovo dispositivo (sdb). Poi lsblk (vedi l'articolo relativo) mostra il disco, e con la colonna TRAN si vede che è collegato via USB. Se lsusb mostra il dispositivo ma il kernel scrive errori come device descriptor read/64, error -71, il problema è fisico: cavo, porta o alimentazione. Se lsusb non lo mostra proprio, il sistema non lo vede affatto. Le righe sono illustrative, ma riprendono i messaggi tipici del kernel.
Esempio 6: gli stessi dati senza lsusb
$ cat /sys/bus/usb/devices/1-2/idVendor
0781
$ cat /sys/bus/usb/devices/1-2/product
Ultra
$ cat /sys/bus/usb/devices/1-2/speed
480
$ usb-devices | head -n 8Come per lspci, i dati arrivano dal kernel e sono leggibili direttamente in /sys/bus/usb/devices/: una cartella per dispositivo (1-2 è bus 1, porta 2), con file semplici (idVendor, idProduct, manufacturer, product, speed, serial). È utile su un sistema minimale senza usbutils. Lo stesso pacchetto contiene anche usb-devices, uno script che stampa per ogni dispositivo un blocco di righe (T:, D:, P:, S:, C:, I:), comodo da elaborare con grep o awk. Gli esempi sono illustrativi: in questa macchina di prova non c'è niente da leggere.
Esempio 7: uso negli script
#!/bin/bash
# Controlla che le periferiche attese siano collegate (ID costruttore:modello)
ATTESE="046d:c31c 0781:5581"
MANCANTI=0
ELENCO=$(lsusb)
for ID in $ATTESE; do
if ! echo "$ELENCO" | grep -q -i "ID $ID"; then
echo "Periferica non trovata: $ID" >&2
MANCANTI=$((MANCANTI + 1))
fi
done
[ "$MANCANTI" -eq 0 ] && echo "Tutte le periferiche sono collegate"
exit "$MANCANTI"Lo script cerca nell'elenco gli ID attesi, e il codice d'uscita è il numero di quelli mancanti (0 = tutto bene: lo si può usare con cron, vedi l'articolo su crontab). Gli ID sono stabili anche quando cambia il numero del dispositivo, per questo si usano al posto di Bus e Device. L'ho provato nel sandbox con un finto lsusb che stampa tre righe: con entrambe le periferiche presenti risponde "Tutte le periferiche sono collegate" con codice 0; dopo aver tolto la tastiera, segnala quella mancante con codice 1; e con il vero lsusb (che qui non ha niente da elencare) le segnala tutte e due, con codice 2. Un dettaglio: l'ID viene cercato con grep -i, che ignora la differenza tra maiuscole e minuscole, perché gli esadecimali si possono scrivere in entrambi i modi.
Opzioni utili
lsusb: elenco;-t: albero con classi, driver e velocità;-v: descrittori completi (lunghi).-d costruttore:modello: filtra per ID (anche-d costruttore:);-s bus:numero: filtra per posizione (in decimale).-D dispositivo: esamina un dispositivo indicato per percorso (/dev/bus/usb/BBB/DDD).usb-devices: un blocco di righe per dispositivo, adatto agli script.usbreset: "ricollega" per programma una periferica, senza staccarla (nello stesso pacchetto: guarda l'aiuto conusbresetsenza argomenti, prima di usarlo)./sys/bus/usb/devices/: i dati grezzi;/usr/share/misc/usb.ids: l'archivio dei nomi (si aggiorna con il pacchettousb.ids).dmesg -w,lsblk,lspci,lsmod: i messaggi del kernel, i dischi, i dispositivi PCI, i moduli.
Attenzione a
- Vede solo ciò che il sistema ha riconosciuto a livello USB: se una periferica non compare, il problema è prima del driver: cavo, porta, alimentazione (un disco esterno da 2,5 pollici può chiedere più corrente di quella che la porta dà), o la periferica stessa. Prova un'altra porta e un altro cavo, e guarda
dmesg. - Un elenco vuoto non vuol dire "niente collegato": in una macchina virtuale o in un container, senza controller USB (o senza accesso a quelli della macchina ospite),
lsusbnon stampa niente. In una macchina virtuale le periferiche si assegnano esplicitamente dall'ambiente di virtualizzazione. - I numeri
BuseDevicecambiano: dopo aver scollegato e ricollegato una periferica, il numero diDeviceaumenta. Negli script e nelle regole usa l'IDcostruttore:modello(o il numero di serie), non la posizione. - I nomi dipendono dall'archivio: se il dispositivo è recente o poco comune, mostra solo l'ID o un nome generico. Il nome non è un'informazione di sicurezza: molti dispositivi dichiarano un costruttore e un modello a piacere, e un adattatore economico può presentarsi con l'ID di un'altra marca. Per questo gli ID non provano l'identità della periferica.
- Le periferiche USB possono essere un rischio: una chiavetta sconosciuta può presentarsi come tastiera e inviare comandi (si parla di dispositivi "BadUSB"). Su un server, dove l'accesso fisico alle porte è controllato,
lsusbè un modo semplice per verificare che non ci sia nulla di inatteso collegato. - Speed e porte: un dispositivo USB 3 collegato a una porta USB 2 funziona, ma a
480M; controlla la colonna di velocità inlsusb -tquando un disco sembra lento. - Non monta e non smonta niente:
lsusbmostra che la chiavetta c'è, ma per usarla serve montarla (vedimountelsblk). Per scollegarla in sicurezza, smonta prima il file system, altrimenti rischi di perdere dati.
Riepilogo
| Comando | Cosa fa |
|---|---|
lsusb | Elenca i dispositivi USB |
lsusb -t | Albero con classe, driver e velocità |
lsusb | grep -i nome | Cerca un dispositivo per nome |
lsusb -d 0781: | Filtra per costruttore (o 0781:5581 per modello) |
lsusb -s 1:4 | Filtra per bus e numero |
sudo lsusb -v -d 0781:5581 | Dettaglio completo di un dispositivo |
usb-devices | Un blocco di righe per dispositivo, per gli script |
sudo dmesg -w | Segue i messaggi del kernel mentre si collega |
cat /sys/bus/usb/devices/1-2/product | Legge i dati grezzi dal kernel |