Per comprendere i concetti di redirezione e di pipe, è necessario spiegare alcune nozioni sui processi ancora non discusse. In Unix ciascun processo (incluse le applicazioni grafiche) apre un minimo di tre diversi descrittori del file: lo standard input, lo standard output e lo standard error. I numeri assegnati a questi tre sono rispettivamente 0, 1 e 2. Generalmente i tre descrittori vengono associati al terminale dal quale è stato lanciato il processo, e, in particolare, lo standard input è associato alla tastiera. Lo scopo della redirezione e delle pipe è, appunto, di redirigere questi tre canali. Gli esempi che seguono ve lo mostreranno chiaramente.
Immaginate di voler visualizzare una lista di tutti i file che terminano con .gif[1] nella directory images. Visto che l'elenco è molto lungo, volete salvarlo in un file per consultarlo con comodo in seguito. Per farlo potete usare questo comando:
$ ls images/*.gif 1>file_list
Questo significa che lo standard output di questo comando (1) viene rediretto (>) verso il file chiamato file_list. Il carattere > è l'operatore di redirezione dell'output. Se il file specificato nella redirezione non esiste, viene creato al momento, mentre se esiste il suo contenuto viene sovrascritto. Se in un comando di redirezione che usa questo operatore non viene specificato un descrittore, la shell assume che vogliate utilizzare lo standard output; volendo quindi potreste scrivere, più semplicemente:
$ ls images/*.gif >file_list
e otterreste il medesimo risultato. Poi potreste leggere il contenuto del file con un comando come less.
Ora immaginate di voler contare quanti file di quel tipo ci sono. Piuttosto che contarli a occhio, potreste utilizzare il comando wc (Word Count) con l'opzione -l, che scrive sullo standard output il numero di parole contenute in un file. Una soluzione potrebbe quindi essere:
wc -l 0<file_list
e in questo modo raggiungereste lo scopo. Il carattere < è l'operatore di redirezione dell'input, e il descrittore su cui questo agisce per opzione predefinita è lo standard input, ovvero lo 0; quindi potreste digitare anche
wc -l <file_list
Ora immaginiamo che vogliate prendere questo file, rimuovere tutte le "estensioni" e scrivere i risultati dell'operazione in un altro file. Uno strumento adeguato per questo scopo è sed, ovvero Stream EDitor. Vi basterà redirigere lo standard input di sed verso il file file_list e redirigere invece l'output verso il file the_list:
sed -e 's/\.gif$//g' <file_list >the_list
questo creerà con un'unica operazione una lista pronta per essere consultata con un qualsiasi programma adatto allo scopo.
Spesso può essere utile anche redirigere gli standard error, ovvero il canale in cui i processi riversano i loro messaggi di errore. Per esempio, se volete scoprire a quali directory contenute in /shared non potete accedere, potreste elencare ricorsivamente queste directory e redirigere gli errori in un file, senza visualizzare lo standard output:
ls -R /shared >/dev/null 2>errors
che significa che lo standard output verrà rediretto (>) verso /dev/null, un file che ha la caratteristica di eliminare qualsiasi cosa vi si scriva (in questo caso, redirigere lo standard output verso null ne impedisce la visualizzazione); allo stesso tempo il canale standard error (2) viene rediretto (>) verso il file errors.
Le pipe sono una sorta di combinazione di redirezione dell'input e dell'output. Il principio è quello di una tubazione, da cui il nome (che significa appunto 'tubo, condotto'). L'operatore di pipe è |. Riprendiamo l'esempio della lista di file, supponiamo che vogliate trovare direttamente quanti sono i file corrispondenti, senza immagazzinare il risultato in un file temporaneo: per farlo potreste usare il comando
ls images/*.gif | wc -l
che significa che lo standard output del comando ls (ovvero l'elenco dei file) viene rediretto verso lo standard input del comando wc. Questo produce il risultato che cercate.
Potete anche creare una lista dei file "senza estensioni" usando questo comando:
ls images/*.gif | sed -e 's/\.gif$//g' >the_list
o, se volete consultare la lista direttamente, senza salvarla in un file:
ls images/*.gif | sed -e 's/\.gif$//g' | less
L'uso delle pipe e della redirezione non è limitato ai file di testo, leggibili dall'uomo. Ad esempio, lanciando questo comando da una console di xterm:
xwd -root | convert - ~/my_desktop.gif
viene creata un'istantanea del vostro desktop che viene salvata nel file my_desktop.gif[2] nella vostra directory personale.
[1] | Potreste pensare che sia strano parlare di "file il cui nome termina per .gif" piuttosto che "immagini GIF". Tuttavia, ricordiamolo ancora, i file in un sistema Unix non sono necessariamente identificati dalla loro estensione: in questo ambiente le estensioni non definiscono il tipo di file. Un file il cui nome termina per .gif potrebbe tranquillamente essere un'immagine JPEG, un programma, un file di testo o di qualsiasi altro tipo. |
[2] | E in questo caso - avete indovinato - sarà veramente un'immagine GIF :-) |
Indietro | Partenza | Avanti |
I caratteri speciali (meta-caratteri) e le espressioni regolari nella shell | Risali | Completamento automatico |