dd è un comando Unix, originariamente concepito per convertire e copiare file a basso livello. Il nome deriva da data duplicator ed è uno strumento fondamentale, presente in ogni distribuzione Linux e sistemi macOS, per chiunque lavori con dischi, immagini e backup a livello raw.
A differenza di comandi come cp, dd non conosce il concetto di filesystem: lavora direttamente con i blocchi di dati. Questo lo rende straordinariamente versatile ma anche pericoloso: un errore nella destinazione può sovrascrivere irrimediabilmente un intero disco.
Come funziona
Il funzionamento di dd si basa su un concetto semplice: legge un flusso di dati da una sorgente (input file) e lo scrive su una destinazione (output file). Entrambi possono essere file regolari, dispositivi a blocchi (/dev/sda), dispositivi speciali (/dev/zero, /dev/null, /dev/urandom) o persino la stdin/stdout.
Il parametro centrale della performance è il block size (bs): la quantità di dati letti e scritti in ogni operazione. Un block size più grande riduce le chiamate di sistema e aumenta la velocità di trasferimento, ma occupa più RAM. Il valore predefinito è 512 byte (la dimensione storica di un settore disco), ma oggi valori come 4M o 8M sono comuni per massimizzare le prestazioni.
Sintassi
La sintassi base del comando e la seguente
dd if=sorgente of=destinazione [bs=dimensione] [count=N] [skip=N] [seek=N]e questi sono i principali parametri utilizzati
- if= – Input file, la sorgente dei dati (file, device, pipe)
- of= – Output file, la destinazione dei dati
- bs= – Block size, dimensione del blocco di lettura/scrittura (es. 512, 4K, 1M)
- count= – Numero di blocchi da copiare (se omesso, copia tutto)
- skip= – Blocchi da saltare all’inizio dell’input
- seek= – Blocchi da saltare all’inizio dell’output
- conv= – Conversioni: noerror, sync, notrunc, fdatasync, ecc.
- status= – Livello di output: none, noxfer, progress
Vediamo ora alcuni esempi di utilizzo del comando dd
Immagine di un disco o partizione
Uno degli usi più comuni è quello di creare un backup raw di un intero disco o di una partizione, byte per byte
dd if=/dev/sde of=/backup/disco.img bs=4M status=progressPer procedere al ripristino del backup il comando è il seguente
dd if=/backup/disco.img of=/dev/sde bs=4M status=progress conv=fdatasyncMasterizzare un’immagine ISO su una chiavetta USB
dd è il metodo più diretto per creare USB avviabili partendo da immagini ISO (tramite il comando lsblk è possibile individuare il device della chiavetta). Va prestata attenzione nel sostituire il device reale della chiavetta (/dev/sdc) e non una partizione (/dev/sdc1)
dd if=/home/utente/ubuntu-24.04.iso of=/dev/sdX bs=4M conv=fdatasync status=progressCancellare in modo sicuro un disco
Sovrascrivere un disco con zeri o dati casuali rende il recupero dei dati molto più difficile rispetto a una semplice formattazione
# Sovrascrittura con zeri (veloce)
dd if=/dev/zero of=/dev/sde bs=4M status=progress
# Sovrascrittura con dati casuali (più sicura)
dd if=/dev/urandom of=/dev/sde bs=4M status=progressCreare un file di dimensione fissa
dd può generare file di qualsiasi dimensione, utile ogni volta che hai bisogno di un file “vuoto” di dimensioni precise per test, simulazioni o configurazioni di sistema
# Crea un file da 1 GB pieno di zeri
dd if=/dev/zero of=test.img bs=1M count=1024Backup e ripristino del MBR
Il MBR (Master Boot Record) occupa i primi 512 byte del disco e contiene il bootloader e la tabella delle partizioni. Farne un backup può spesso essere utile
# Backup MBR (512 byte)
dd if=/dev/sda of=mbr_backup.bin bs=512 count=1
# Ripristino MBR (senza sovrascrivere la tabella delle partizioni)
dd if=mbr_backup.bin of=/dev/sda bs=446 count=1
# 446 byte = solo bootloader, senza toccare partition table (byte 447-512)Test delle prestazioni di un disco
dd è spesso usato per misurare la velocità di lettura e scrittura di un dispositivo
# Test velocità di scrittura
dd if=/dev/zero of=/tmp/test_write bs=1M count=2048 conv=fdatasyncCopiare solo una porzione di disco (skip e seek)
A volte non serve copiare un intero disco: skip e seek permettono di lavorare su porzioni specifiche, saltando blocchi all’inizio della sorgente o della destinazione. Questo è utile per recuperare dati da un disco parzialmente danneggiato, aggiornare una sezione specifica di un’immagine senza riscriverla tutta, o spostare una partizione all’interno di un file immagine
# Copia 100 MB a partire dal blocco 200 dell'input
# e li scrive a partire dal blocco 50 dell'output
dd if=sorgente.img of=dest.img bs=1M skip=200 seek=50 count=100I valori dipendono dal parametro bs scelto, perché skip e seek si esprimono in numero di blocchi, non in byte. La formula è
numero_blocchi = offset_in_byte / block_sizeNel comando di esempio abbiamo utilizzato bs=1M quindi avremo
- skip=200, inizio lettura a 200 MB su sorgente
- seek=50, inizio scrittura a 50 MB su destinazione
- count=100, copia 100 MB in totale
Se invece volessi copiare la stessa porzione di dati utilizzando bs=512, il comando diventerebbe
dd if=sorgente.img of=dest.img bs=512 skip=411648 seek=102400 count=204800In questo caso il trasferimento è più lento perché dd fa molte più chiamate di sistema ma è utile quando si lavora direttamente con settori di disco. Vengono inoltre utilizzati i valori di fdisk senza necessità di calcoli in quanto i settori e i blocchi coincidono 1:1
Infine, se avessimo utilizzato bs=2M, il comando diventa
dd if=sorgente.img of=dest.img bs=2M skip=100 seek=25 count=50Con bs=2M bisogna prestare attenzione: gli offset di skip e seek devono essere multipli esatti del block size. In questo caso funziona perché 200 MB e 50 MB sono entrambi divisibili per 2 MB senza resto. Se l’offset fosse ad esempio 201 MB, il risultato sarebbe 201 / 2 = 100.5, un valore non intero che dd non può usare, e si rischierebbe di leggere o scrivere nel posto sbagliato
Monitorare il processo
Per versioni del comando dd recenti (coreutils ≥ 8.24), è possibile usare l’opzione status=progress per vedere l’avanzamento in tempo reale del processo di copia
dd if=/dev/sde of=backup.img bs=4M status=progress
