Bene, ragazzi, siamo al numero estivo, e mi prendo un po' di vaccanze pure io, come potete vedere dalla brevità di questo articolo. D'accordo, sarebbe stato più logico che io avessi scritto di più, visto che da un lato voi avete maggior tempo per leggere, e d'altro canto le linee dovrebbero essere meno cariche e lasciarvi scaricare questo numero di BETA più velocemente. Fa lo stesso. Sono pigro, la scadenza è vicina, e non me la sento proprio di mettermi a sbrodolare sulla tastiera[1] tra l'afa e le zanzare.
In compenso, penso che l'argomento di questo numero sia abbastanza interessante: tratterò infatti di dd, il data duplicator, un programma relativamente poco conosciuto, ma che trovo utilissimo per mille cose che nessuno sospetterebbe a prima vista. Prima di presentare il comando in tutte le sfaccettature, voglio però narrare una leggenda che spiega perché la sua sintassi sia così buffa - altro che find!. Purtroppo non ricordo la fonte di quanto dirò[2], il che però nulla toglie al soffio di antichità che pervade la storia, e che ci fa sentire così piccoli...
La leggenda narra che nella notte dei tempi, quando nacque il primo UNIX, i suoi creatori ebbero bisogno a un certo punto di un comando a basso livello per copiare dati da un device all'altro. Visto però che avevano fretta, non si misero a studiare la sintassi del comando, e copiarono di peso quella usata nei mainframe IBM-360; tanto ci sarebbe stato tempo di definire un comando dall'interfaccia consistente con gli altri. Il tempo passò, e tutti si erano così abituati alle idiosincrasie di dd, che a nessuno venne in mente di riscrivere un comando simile. Sarà vero? Non lo so, ma ribadisco che sarebbe comunque bene inventato. Ma vediamo in dettaglio come esso funziona.
A dire il vero, dd non è completamente diverso dagli altri comandi Unix: anch'esso è infatti un filtro, che cioè legge per default dallo standard input e scrive sullo standard output. Insomma, se si scrive semplicemente "dd" e si preme return, il terminale rimane tranquillo[3]. Si può scrivere quello che si vuole, e terminare con ctl-D; a questo punto verrà riscritto quanto digitato, e poi dd aggiungerà la sua firma, del tipo "0+10 records in <CR> 0+1 records out", tanto per divertirsi un po'[4].
Bando alle ciance: la sintassi completa del comando è la seguente.
dd [if=file] [of=file] [ibs=bytes] [obs=bytes] [bs=bytes] [cbs=bytes] [skip=blocks] [seek=blocks] [count=blocks] [conv={ascii,ebcdic,ibm,block, unblock,lcase,ucase,swab,noerror,notrunc,sync}]
Insomma, tutte le opzioni sono della forma variabile=valore. Attenzione: non si può mettere nessuno spazio né prima né dopo il segno di uguale. Questo rompeva un po' le scatole un tempo, visto che la shell non espandeva i nomi di file in questa situazione e occorreva digitarselo tutto; fortunatamente la bash di Linux è abbastanza intelligente da accorgersi del contesto e fare ugualmente funzionare l'espansione. In pratica, nicc problema!
Altra cosa importante da ricordare è che tutti i valori che accettano bytes possono essere seguiti da un moltiplicatore. La versione Linux di dd riconosce b per blocco (512), k per kilobyte (1024), w per word (2), e xm per moltiplicare per un numero m; questo diventa poi il valore di block.
Qui sotto è data una spiegazione più completa delle varie opzioni.
L'esempio canonico di uso di dd è quello in cui vi sarete certamente imbattuti quando avete creato il vostro primo dischetto Linux: come scrivere su un floppino senza mettere su il filesystem MS-DOS. La soluzione è semplice:
% dd if=disk.img of=/dev/fd0 obs=18k count=80Ho deciso di non usare ibs perché non so quale sia il miglior valore per un hard disk; potevo comunque usare bs al posto di obs e sarebbe andato tutto perfettamente. Da notare il fatto che per sicurezza ho anche indicato il numero di settori da scrivere (80), e che ho scritto direttamente sul nome a basso livello del floppy.
Un'altra utile applicazione di dd capita nel caso di backup in rete. Supponiamo di essere sulla macchina alpha, e che sulla macchina beta ci sia un nastro /dev/rst0 con un file tar che ci interessa, abbastanza grande da non potere essere salvato su beta e poi copiato. In questo caso, si può scrivere
% rsh beta 'dd if=/dev/rst0 ibs=8k obs=20k' | tar xvBf -per fare l'operazione in un singolo passo. In questo caso, abbiamo sfruttato rsh per leggere dal nastro: le dimensioni di input e di output sono messe al default per queste operazioni, cioè 8KB per leggere da nastro e 20KB per scrivere sulla ethernet. Dal punto di vista del nostro tar locale, i byte che arrivano sono esattamente quelli che avrebbe visto da nastro, a parte il modo un po' strano con cui arrivano, ragion per cui ho aggiunto l'opzione B al comando[6].
Infine, un rapido comando che può tornare utile quando arriva un file Word da Mac, e si scopre che nonostante tutte le controconversioni questo rimane illeggibile perché scritto in MacBinary: basta togliere i primi 128 byte.
% dd if=file.bad of=file.doc ibs=128 skip=1
Insomma, fa sempre comodo avere sotto mano il nostro duplicatore di dati![7]