Comandi Unix buffi: tar

Caro lettore,
ti eri accorto che avevo dimenticato una delle opzioni di sort, nell'articolo del numero scorso? No? Male. O magari bene: non he hai mai avuto bisogno, e ciò è bello, perché significa che non è che poi hai tantissimo da ordinare, o che hai tanto spazio. L'opzione saltata per un refuso[1] è infatti -T tmpdir, e serve a specificare un'altra directory dove fare a scrivere i file temporanei di cui sort ha bisogno. In genere, infatti, viene usata /tmp, ma a volte può essere necessario spostarsi in caccia di posto libero. Tra l'altro, il GNU sort deve essere stato scritto da qualcuno abituato a lavorare sotto DOS: se infatti esso trova settata la variabile di ambiente TMPDIR, usa quel valore come directory di lavoro.

Questa volta tocca a tar. Il nome sta per "tape archiver", cioè archiviatore su nastro: ma oramai sei abbastanza smaliziato per sapere che le probabilità di usare il comando su un vero nastro sono ben poche. Intendiamoci: se il tuo sysadm ha configurato le cose per bene e tu hai un'unità nastro, puoi archiviarci i tuoi file scrivendo semplicemente tar c . (il punto è parte del comando, non finisce la frase!). Ma visto che tanto la risposta sarà più o meno tar: can't open /dev/rmt0 : Permission denied o qualcosa di simile, ti conviene lasciare perdere e metterti a leggere i veri usi del comando. Una nota: se non hanno migliorato la man page nelle ultime versioni, il GNU tar è proprio incomprensibile. Peccato.

Funzioni fondamentali

Il comando mostrato sopra fa comunque già notare la prima peculiarità: non si usa il - davanti alle opzioni. Questo non è totalmente vero: in un impeto di bontà, nelle versioni attuali di tar è comunque possibile far precedere le opzioni dal carattere '-' senza che il sistema si preoccupi. In genere, comunque, la sintassi del comando è questa:

   tar {un gruppone di lettere} {un po' di parametri relativi
       alle lettere stesse} [ -I file_include ] file(s) 
       [ -C directory file]
il che dice poco o nulla. Specificando qualcosa in più, scopriamo che alcune lettere del "gruppone" rappresentano le funzioni fondamentali del comando, e ce ne può essere una e una sola, che si mette in genere come primo carattere tanto per ricordarsi cosa si sta facendo. Le altre lettere possono essere presenti o no; se lo sono, e inoltre hanno dei parametri, questi sono indicati nello stesso ordine in cui la lettera corrispondente si trova nel gruppone. Non ci sono quindi problemi di parsificazione per il sistema; magari ne rimane qualcuno per il povero utente, che deve spostarsi avanti e indietro tra il gruppone e i parametri per capire chi si riferisce a cosa.

Il file non è un semplice nome, o per meglio dire una semplice espressione regolare come ad esempio "*": se infatti corrisponde a una directory, viene lanciata la ricorsione e quindi tar comincia a infilarsi nei meandri del file system riportando alla luce reperti imprevisti. La ricorsione è fatta per bene, e comprende anche i file i cui nomi iniziano con un punto e pertanto sono nascosti; insomma, se si vuole salvare tutto un sottoalbero basta partire da ".".

Le funzioni principali sono cinque: c, r, t, u, x.

il GNU tar, per non smentirsi, ne ha aggiunte altre due, che non sono comunque così necessarie almeno a mio parere:

Ah, dimenticavo: il GNU tar permette sempre di scrivere per esteso i nomi delle funzioni, facendoli precedere da -- (due segni meno). Serve? non serve? per me è solo una perdita di tempo.

Funzioni modificanti

Nel cosiddetto gruppone, ci sono davvero tante lettere. Parlerò qui solo delle principali, vista la mia solita pigrizia. Tanto non capita praticamente mai di usarle tutte! Come ho detto sopra, se la funzione ha un parametro, questo lo si trova bello ordinato dopo il gruppone stesso.

Tanto per darti un'idea, ho lasciato da parte le seguenti funzioni per il tar Solaris: e,F,FF,i,l,m,o. Il GNU tar ha invece le seguenti funzioni denominate con una lettera: F,G,g,i,k,K,L,m,o,O,R,s,S,T,V,W, oltre che un'altra dozzina per cui non si erano trovate lettere dell'alfabeto disponibili[4]. Non è detto che le opzioni corrispondano: F,i, ed o sono infatti cose diverse. Esistono anche funzioni definite da una cifra tra 0 e 7, che serve a specificare un device file differente.

Alcune funzioni GNU sono però simpatiche, e vale la pena di darci un'occhiata.

Funzioni separate

Le due funzioni che se ne stanno da sole sono, come visto sopra, -I include_file e -C directory file. La prima funziona più o meno come X: si apre il file e si legge la lista di file su cui occorre operare. Attento a non usare spazi, che verrebbero considerati parte del file, e ricordati che se un file è contemporaneamente incluso ed escluso, quest'ultima condizione prevale.

La funzione -C è un po' più delicata. Viene usata solo con le funzioni c ed r, e richiede esattamente due parametri: il programma usa il primo come argomento di una chdir, e quindi si posiziona altrove, e il secondo indica quale file (ricorsivamente) salvare. In pratica, si ha la possibilità di salvare file sotto directory scorrelate senza dovere partire dalla radice e selezionare solo le parti che interessano. Meglio che niente anche in questo caso.

Esempi

Un paio di esempi non fanno certo male. Cominciamo con la cosa più usuale: estrarre un pacchetto in formato .tar.gz. Il comando da darsi sotto GNU tar (magari dopo avere controllato con tar tvzf pippo.tar.gz | head se occorre lasciare il file in una directory propria oppure se la crea lui) è

   % tar xvzf pippo.tar.gz
con la v facoltativa. Non si ha il GNU tar? nessun problema: la soluzione è allora
   % zcat pippo.tar.gz | tar xvf -
in cui si vede anche con piacere il fatto che lo pseudofile - in questo caso indica lo standard input.

Se si vuole creare un file tar con la directory pippo e tutti i file sottostanti, la risposta è data da

   % tar cvf pippo.tar pippo
(meglio che posizionarsi in pippo e scrivere tar cvf ../pippo.tar . - almeno a mio parere.

Se si vuole copiare un sottoalbero da un'altra parte in un solo colpo, non si può usare cp, come ormai sanno anche i bambini; tar è proprio quello che ci vuole, usato due volte in una pipe.

   % cd fromdir; tar cf - | (cd todir; tar xf -)
Avendo una pipe, dobbiamo chiaramente usare lo pseudofile - in entrambi i casi; ci serve inoltre racchiudere il secondo comando in una sottoshell, perché dobbiamo essere certi che il file sia salvato nella directory corretta. Altrimenti, la pipe terminerebbe con il cd, si perderebbe tutto l'input e il secondo tar non saprebbe da dove prendere i dati.

Infine, un comando d'alta scuola: un tar in rete. Supponiamo di avere un nastro su un'unità remota e di volerlo utilizzare. Purtroppo non abbiamo la possibilità di copiare tutti i nostri file sul calcolatore remoto, e comunque siamo talmente innamorati delle pipe che vogliamo sfruttarle ad ogni pié sospinto. Bene: se sei stato attento, saprai che b e B dovranno servirci perché abbiamo un nastro e lavoriamo in rete, e rsh non è certo dimenticato. Tutto qui? No. Ovviamente non si può usare tar da ambo le parti. Ci si incasinerebbe con le dimensioni dei blocchi. Ma niente paura, c'è il nostro vecchio amicone dd! Ecco in primo luogo come si salva il sottoalbero che parte da pippo su un nastro remoto sulla macchina server1:

   % tar cvfb - 20 pippo | rsh server1 dd of=/dev/rmt/0 obs=20b
Occorre che la dimesione del blocco per i due comandi sia la stessa. Oltre 20 non si può andare: accontentiamoci. L'operazione inversa è leggermente diversa:
   % rsh -n server1 dd if=/dev/rmt0 bs=20b | tar xvbBf 20 - 
In questo caso occorre da un lato dare entrambe le dimensioni dei blocchi a dd, dall'altra ricordarsi che il tar in ingresso riceverà dati a spizzichi e bocconi, e che occorrerà pertanto tranquillizzarlo un po' con la funzione B. Ma non preoccuparti più di tanto se te la dimentichi: un tar decente si accorge di essere in una pipe e te la potrebbe aggiungere di tuo!

Una parolina finale

La miniserie dedicata ai "comandi buffi Unix" è così terminata: ti sei cuccato find, dd, sort e tar, che in realtà sono i comandi più usati che hanno un'interfaccia relativamente strana. Non sono gli unici, a dire il vero: a me viene ad esempio in mente cpio che è abbastanza simile a tar per non valer la pena di studiarlo, e dump che oggi è relativamente poco usato, perché nascosto all'interno dei programmi di backup. In pratica si può comunque affermare che la sintassi di tutti gli altri comandi è sempre la stessa. Pensaci un attimo: non ti rincuora sapere di potere contare su un po' di sana monotonia?

Il problema è adesso mio. Infatti, devo decidere cosa scrivere nei prossimi numeri. Non ci crederai, ma alle volte è più difficile stabilire cosa scrivere che mettermi poi davvero a scriverlo. Idee? Beh, potrei continuare a trattare i comandi Unix (ls, o grep, o persino bc, ad esempio); oppure sviscerare qualche segreto sui programmi di utilità che si trovano spesso inseriti proditoriamente negli shell script e che si danno per scontate, come awk e sed; o ancora scrivere di vi, l'editor del Vero Programmatore quando non è di fretta[6]. Siccome so che tu sei intelligente, immagino che hai già sentito puzza di feedback. Perché non mi mandi una letterina con le tue preferenze? Possibilmente prima di Natale, anche se non ti regalerò nulla...

Note & Chiose

[1]
Dicono sempre così...
[2]
In realtà sarebbe il TOC, o Table of Contents: ma in pratica lo si usa per vedere se va tutto bene!
[3]
Che è un'unità a nastro formato pizza. Reperto da museo, insomma. Ma questo è nulla rispetto a cat, anzi C/A/T ...
[4]
Che siano stati gli amici GNU a fare lobbying per Unicode, in modo da avere decine di migliaia di caratteri disponibili?
[5]
Barando, però: infatti occorre che il comando di (de)compressione sia presente nel path.
[6]
Il Vero Programmatore quando ha fretta usa ed, che non lo infastidisce con prolissi messaggi di errore, e quando ha veramente fretta scrive direttamente con cat>nomefile quello che gli serve.
.mau.
Copyright © 1996 Maurizio Codogno e BETA. Questo testo può essere liberamente distribuito purché non a fini di lucro. Per ogni altro utilizzo, si prega contattare l'autore.