Il nome di un disco può cambiare da un avvio all'altro: la chiavetta che oggi è /dev/sdb domani può diventare /dev/sdc. Per riconoscere un file system in modo affidabile si usano invece l'etichetta e l'UUID, che sono scritti nel file system stesso. Il comando che li legge è blkid.
Cos'è
blkid (block ID) fa parte di util-linux e usa la libreria libblkid, la stessa che adoperano mount, lsblk e udev per identificare i dispositivi. Dato un dispositivo, o un file immagine, ne riconosce il contenuto: tipo di file system, etichetta, UUID, oppure il tipo di tabella delle partizioni, o lo swap.
Cosa fa
Legge i primi byte (e altre posizioni note) del dispositivo, cerca le "firme" dei file system e stampa quello che trova, in formati diversi a seconda delle opzioni. Con alcune opzioni fa anche il lavoro inverso: dato un UUID o un'etichetta, trova il dispositivo corrispondente. Non modifica niente: è un comando di sola lettura, quindi innocuo.
Come si usa
$ sudo blkid [opzioni] [DISPOSITIVO...]Senza argomenti elenca tutti i dispositivi a blocchi del sistema. Servono i permessi di root per leggere i dispositivi (con un utente normale blkid può mostrare solo ciò che ha in cache: ho lavorato come root e non l'ho provato). Negli esempi uso immagini di disco: i nomi come /dev/sdb1 sono invece esempi. Gli output sono di blkid 2.39.3; ho accorciato gli UUID con i puntini per tenere le righe corte.
Esempio 1: identificare un dispositivo
$ sudo blkid e.img v.img x.img b.img s.img
e.img: LABEL="dati" UUID="74ca4709-..." BLOCK_SIZE="4096" TYPE="ext4"
v.img: SEC_TYPE="msdos" LABEL_FATBOOT="CHIAVE" LABEL="CHIAVE" UUID="CDFF-393C"
BLOCK_SIZE="512" TYPE="vfat"
x.img: LABEL="xfsdati" UUID="599e29b5-..." BLOCK_SIZE="512" TYPE="xfs"
b.img: LABEL="btdati" UUID="6c90cf7b-..." UUID_SUB="1317e26a-..."
BLOCK_SIZE="4096" TYPE="btrfs"
s.img: LABEL="swp" UUID="0d12387d-..." TYPE="swap"Ho creato cinque immagini con mkfs.ext4, mkfs.vfat, mkfs.xfs, mkfs.btrfs e mkswap: blkid le riconosce tutte e per ciascuna mostra etichetta, UUID e TYPE. Alcune righe le ho spezzate (la seconda parte inizia con uno spazio) per non allargare la pagina: sul terminale sono su una riga sola. Per il FAT compaiono anche SEC_TYPE e un UUID corto di 8 caratteri; per Btrfs un UUID_SUB aggiuntivo.
Esempio 2: stampare solo ciò che serve
$ sudo blkid -s TYPE e.img v.img
e.img: TYPE="ext4"
v.img: TYPE="vfat"
$ sudo blkid -o value -s TYPE e.img
ext4
$ sudo blkid -o value -s LABEL e.img
dati-s TAG limita l'output a un campo (TYPE, LABEL, UUID...); -o value toglie il nome del campo e il dispositivo, lasciando solo il valore: la forma ideale per gli script, perché si cattura con $(...). Se il dispositivo non ha il campo richiesto non stampa niente.
Esempio 3: altri formati di output
$ sudo blkid -o export e.img
DEVNAME=e.img
LABEL=dati
UUID=74ca4709-8306-44dc-b799-3b13ffaaeb25
BLOCK_SIZE=4096
TYPE=ext4
$ sudo blkid -o list e.img v.img
device fs_type label mount point UUID
e.img ext4 dati (not mounted) 74ca4709-8306-44dc-b799-3b13ffaaeb25
v.img vfat CHIAVE (not mounted) CDFF-393C-o export stampa una variabile per riga, nel formato NOME=valore: si può caricare in uno script con eval (ho provato eval "$(blkid -o export DEV)", che ha impostato TYPE e LABEL), ma attenzione alle etichette con spazi o simboli, che rompono eval. -o list è una tabella leggibile che indica anche se il dispositivo è montato. Esiste anche -o udev, che stampa le variabili ID_FS_LABEL, ID_FS_UUID e simili usate dalle regole di udev.
Esempio 4: trovare un dispositivo dall'etichetta o dall'UUID
$ sudo blkid -L dati
/dev/sdb1
$ sudo blkid -U CDFF-393C
/dev/sdc1
$ sudo blkid -t TYPE=vfat
/dev/sdc1: LABEL="CHIAVE" UUID="CDFF-393C" TYPE="vfat"
$ sudo blkid -L nonesiste; echo $?
2Qui il discorso si fa interessante e va fatta una precisazione sul mio banco di prova: i nomi /dev/sdb1 e /dev/sdc1 sono illustrativi. Nel sandbox, con le immagini collegate come dispositivi loop con losetup, la stessa ricerca restituiva anche il file immagine (/tmp/bk/e.img), perché blkid ricorda nella sua cache (/run/blkid/blkid.tab) i file già sondati. Su un sistema normale la cache contiene solo dispositivi a blocchi, ma il principio resta: -L, -U e -t si basano sulla cache. -L e -U stampano il dispositivo trovato; -t NOME=VALORE stampa l'intera riga. Se nulla corrisponde il codice di uscita è 2 e non si stampa niente.
Esempio 5: forzare una scansione fresca, senza cache
$ sudo blkid -c /dev/null -t TYPE=vfat
/dev/loop1: SEC_TYPE="msdos" LABEL_FATBOOT="CHIAVE" LABEL="CHIAVE" ...
$ sudo blkid -c /dev/null -t LABEL=dati -o device
/dev/loop0
$ sudo blkid -g-c /dev/null dice a blkid di non usare la cache: rilegge i dispositivi e, nel mio test, ha restituito solo i dispositivi loop, senza i file. L'ultima riga (-g) fa pulizia della cache eliminando le voci dei dispositivi che non esistono più; nel mio sandbox non ha tolto quelle dei file immagine, che esistevano ancora. Se i risultati di blkid ti sembrano "vecchi" dopo aver cambiato un'etichetta, prova prima con -c /dev/null.
Esempio 6: sondaggio a basso livello (-p)
$ sudo blkid -p e.img
e.img: LABEL="dati" UUID="74ca4709-..." VERSION="1.0" FSBLOCKSIZE="4096"
BLOCK_SIZE="4096" FSLASTBLOCK="16384" FSSIZE="67108864" TYPE="ext4"
USAGE="filesystem"
$ sudo blkid p.img
p.img: PTUUID="33cc74ea-..." PTTYPE="gpt"Con -p blkid non usa la cache ed esegue un sondaggio diretto, mostrando campi in più come VERSION, FSSIZE (dimensione del file system in byte) e USAGE. Riconosce anche le tabelle delle partizioni: per un'immagine con una tabella GPT, blkid stampa PTTYPE="gpt" e il suo identificatore, PTUUID. Anche qui ho spezzato le righe e accorciato gli UUID.
Esempio 7: che cosa succede se non riconosce niente
$ blkid vuoto.img; echo $?
2
$ blkid nope.img; echo $?
2
$ blkid --badopt; echo $?
blkid: unrecognized option '--badopt'
1Su un'immagine vuota (nessun file system) blkid non stampa niente e termina con codice 2. Lo stesso accade con un file che non esiste. Un'opzione sbagliata dà codice 1. È un comportamento importante: blkid è il modo più semplice per sapere se un dispositivo è già formattato, ed è quello che ho usato nell'articolo su mkfs. Con -n elenco puoi inoltre limitare i tipi riconosciuti (-n ext4,xfs ha escluso il FAT dal mio test).
Esempio 8: usare etichette e UUID con mount e findfs
$ findfs LABEL=dati
/dev/sdb1
$ findfs UUID=CDFF-393C
/dev/sdc1
$ sudo mount LABEL=dati /mnt
$ sudo umount /mntfindfs è il fratello di blkid -L e -U: dato LABEL=... o UUID=... stampa il dispositivo. Se l'etichetta non esiste scrive findfs: unable to resolve 'LABEL=nonesiste' (codice 1). mount accetta direttamente LABEL= e UUID= al posto del nome del dispositivo, ed è lo stesso meccanismo che usa /etc/fstab. Nel mio test mount LABEL=dati ha montato il dispositivo loop; i nomi /dev/sdb1 e /dev/sdc1 sono ancora illustrativi (le stesse ricerche restituivano il file immagine, per la cache di cui sopra).
Esempio 9: uso negli script
#!/bin/bash
[ $# -eq 2 ] || { echo "uso: $0 dispositivo cartella" >&2; exit 1; }
DEV="$1"
MNT="$2"
tipo=$(blkid -o value -s TYPE "$DEV") || {
echo "nessun file system riconosciuto su $DEV" >&2
exit 1
}
uuid=$(blkid -o value -s UUID "$DEV")
echo "UUID=$uuid $MNT $tipo defaults 0 2"Lo script prepara la riga da aggiungere a /etc/fstab per un dispositivo: legge tipo e UUID con blkid -o value e li compone. Se il dispositivo non ha un file system (blkid esce con codice 2) si ferma con un messaggio, come mostra il ramo ||. Sull'immagine ext4 ha stampato UUID=74ca4709-8306-44dc-b799-3b13ffaaeb25 /mnt/dati ext4 defaults 0 2; sull'immagine vuota e su un file inesistente ha dato errore con codice 1, e senza argomenti il messaggio d'uso. La riga stampata non viene aggiunta a fstab da sola: la controlli tu e la inserisci a mano.
Opzioni utili
-s TAG: mostra solo quel campo (ripetibile).-o value|export|list|udev|device|full: formato dell'output.-L ETICHETTAe-U UUID: cercano il dispositivo corrispondente.-t NOME=VALORE: filtra i dispositivi per un campo (TYPE=ext4,LABEL=dati).-p: sondaggio diretto, senza cache, con più campi.-c FILE: usa un altro file di cache;-c /dev/nulldisattiva la cache.-g: ripulisce la cache dalle voci di dispositivi spariti.-n ELENCOe-u ELENCO: limitano la ricerca a certi tipi di file system o a certi tipi di contenuto (filesystem,raid...).-O BYTEe-S BYTE: con-p, leggono a un certo offset e per una certa dimensione (utile per cercare dentro un'immagine di disco).
Attenzione a
- La cache può mentire: dopo aver cambiato etichetta o UUID, o aver riformattato,
blkidsenza-ppuò mostrare dati vecchi. Usa-po-c /dev/nullper essere sicuro. - Servono i permessi: per leggere i dispositivi serve
sudo. Con un utente normale i risultati potrebbero essere incompleti (non provato, perché il sandbox è root). - UUID non unico dopo una clonazione: se cloni un disco con
ddi due file system hanno lo stesso UUID eblkid -Uomount UUID=possono scegliere quello sbagliato. Cambia l'UUID contune2fs -U. - "Nessun output" non è un errore: un dispositivo senza file system, o con un file system non riconosciuto, non stampa nulla e esce con codice 2. Non significa che sia rotto.
- Un FAT ha due "label":
LABEL_FATBOOTeLABELpossono differire; per i FAT l'UUID è breve (8 caratteri) e il formato è diverso da quello di ext4. - Eval e etichette strane: con
-o exporteevalun'etichetta con spazi o caratteri speciali può rompere lo script (non ho provato etichette di questo tipo). Per gli script è più sicuro-o value -s CAMPO. - Non è
lsblk:lsblk -fmostra tipo, etichetta e UUID in un albero con le partizioni, ma si appoggia al database diudev; nel mio sandbox, senza udev, non mostrava i tipi. Su un sistema normale è l'alternativa più comoda per una panoramica.
Riepilogo
| Comando | Cosa fa |
|---|---|
blkid DEV | Mostra tipo, etichetta e UUID di un dispositivo |
blkid | Elenca tutti i dispositivi riconosciuti |
blkid -o value -s TYPE DEV | Stampa solo il tipo di file system |
blkid -o export DEV | Variabili NOME=valore per gli script |
blkid -L ETICHETTA | Trova il dispositivo con quell'etichetta |
blkid -U UUID | Trova il dispositivo con quell'UUID |
blkid -t TYPE=ext4 | Elenca i dispositivi di un certo tipo |
blkid -p DEV | Sondaggio diretto, senza cache |
blkid -c /dev/null ... | Ignora la cache |
findfs UUID=... | Come blkid -U: stampa il dispositivo |