Salta al contenuto principale

blkid: riconoscere file system, etichette e UUID

Inviato da tuxsa il

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 $?
2

Qui 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'
1

Su 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 /mnt

findfs è 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 ETICHETTA e -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/null disattiva la cache.
  • -g: ripulisce la cache dalle voci di dispositivi spariti.
  • -n ELENCO e -u ELENCO: limitano la ricerca a certi tipi di file system o a certi tipi di contenuto (filesystem, raid...).
  • -O BYTE e -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, blkid senza -p può mostrare dati vecchi. Usa -p o -c /dev/null per 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 dd i due file system hanno lo stesso UUID e blkid -U o mount UUID= possono scegliere quello sbagliato. Cambia l'UUID con tune2fs -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_FATBOOT e LABEL possono differire; per i FAT l'UUID è breve (8 caratteri) e il formato è diverso da quello di ext4.
  • Eval e etichette strane: con -o export e eval un'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 -f mostra tipo, etichetta e UUID in un albero con le partizioni, ma si appoggia al database di udev; nel mio sandbox, senza udev, non mostrava i tipi. Su un sistema normale è l'alternativa più comoda per una panoramica.

Riepilogo

ComandoCosa fa
blkid DEVMostra tipo, etichetta e UUID di un dispositivo
blkidElenca tutti i dispositivi riconosciuti
blkid -o value -s TYPE DEVStampa solo il tipo di file system
blkid -o export DEVVariabili NOME=valore per gli script
blkid -L ETICHETTATrova il dispositivo con quell'etichetta
blkid -U UUIDTrova il dispositivo con quell'UUID
blkid -t TYPE=ext4Elenca i dispositivi di un certo tipo
blkid -p DEVSondaggio diretto, senza cache
blkid -c /dev/null ...Ignora la cache
findfs UUID=...Come blkid -U: stampa il dispositivo