ePrometeusCorsoLinuxLinux
testi articoli
Testi Articoli  Download
Home | Introduzione | Panoramica | Form | Analisi Log | 
CorsoJava è ora Video! Free for all!
Clicca Qui!
Tutorial Perl
Il coltello svizzero di Linux: il Perl
Una questione di feeling
La shell di Unix
Dalla shell al Perl
A cosa serve il Perl
Conclusioni


<<< La shell di Unix >>>

In questo paragrafo evidenzieremo le idee di fondo di Unix, che sono perfettamente in linea con lo scopo dell'articolo in quanto sono esattamente le stesse del Perl. In principio c'era il Multics, che doveva essere un grande sistema operativo, ma in pratica fallì i suoi obiettivi. Lo Unics (poi ribattezzato Unix) nacque per gioco (per davvero - serviva a far girare un videogame) nei laboratori Bell della AT&T come una versione ridotta e monoutente del Multics. Lo Unix era un sistema operativo a linea di comando (come tutti quelli dei sui tempi), ma la caratteristica che lo distingueva dagli altri era l'approccio: lo Unix era pensato per essere un sistema comodo per lo sviluppo di software.


C'è una filosofia dietro Unix, e questo fatto non è chiaro ed evidente a tutti. In pratica lo Unix è un ambiente di sviluppo, e tutti i suoi molteplici comandi sono da considerare non tanto programmi a sè stanti, ma componenti per la costruzione di programmi per l'utente finale. I comandi di Unix vengono scritti in un linguaggio a basso livello, per lo più in C. In questo modo si ha a disposizione una vasta gamma di componenti pronti per l'assemblaggio. Per costruire i programmi, si legano tra di loro i comandi utilizzando script di shell. La system administration è in pratica l'arte di programmare in linguaggio Unix. Per questo lo Unix è così flessibile, ma anche per questo i comandi sono così complessi e densi di opzioni ma non si trova mai quello che fa esattamente quello che serve. I comandi servono per costruire soluzioni, non per averle già belle e pronte.

Perchè questo approccio funzioni, ogni comando di Unix deve essere realizzato in modo da prendere un input, elaborarlo e produrre un output, che cambia a secondo dei parametri specificati sulla riga di comando. L'output prodotto da un comando poi diventa eventualmente l'input per un altro comando. Concatenando l'output di uno all'input di un altro si ottengono utili "pipeline" (tubature) che effettuano le elaborazioni. Per questo motivo in ambiente Linux abbondano i programmi a linea di comando, anche se ultimamente non scarseggiano i programmi interattivi come Midnight Commander o Xwpe. Per semplificare la concatenazione dei comandi, i comandi Unix producono l'output seguendo delle convenzioni. Per esempio vediamo come due comandi tra di loro molto diversi producono in pratica un output simile:


[msciab@guardian /tmp]$ ls -l
total 5
drwxr-x---  15 9543     root         1024 Dec 12 10:33 bigloo1.8
drwxr-sr-x  11 116      111          1024 Apr  5  1996 elk-3.0
drwxr-xr-x   9 215      1002         1024 Dec 12 09:55 guile-src
drwxr-xr-x   2 root     root         2048 Dec 12 09:42 siod
drwxr-xr-x  11 104      111          2048 Jul 25  1995 lout.3.06
 [msciab@guardian /tmp]$ mount
/dev/hda1 on / type ext2 (rw)
none on /proc type proc (rw)
/dev/hdb1 on /archive type ext2 (rw)

In generale l'output di un programma Unix può essere considerato come una tabella, composta da record, e ogni record contiene dei campi. L'output è un testo, diviso in righe: ogni riga rappresenta un record; in una linea i vari campi sono separati da spazi. Molti comandi assumono l'output in questo formato e si comportano di conseguenza. La shell fornisce le funzioni per incanalare l'output di un file nell'input di un altro, in modo di comporli tra di loro. Facciamo un esempio pratico, per evidenziare le idee di fondo di Unix

Consideriamo il problema di trovare le 10 directory più piene del nostro hard disk. Questo è un problema tipico di un sistemista Unix, quando si sta esaurendo lo spazio disco e vuole togliere un po' di file inutili. In ambiente Linux, è disponibile un comando per ottenere tale risultato: du con lo switch -S. Questo comando mostra l'uso disco di una singola directory. L'uso di du però non è sufficiente in quanto mostra il risultato nell'ordine di scansione delle directory:


[root@guardian /tmp]# du -S 
332     ./bigloo1.8/comptime1.8/Cfa
394     ./bigloo1.8/comptime1.8/Integrate
450     ./bigloo1.8/comptime1.8/Cgen
99      ./bigloo1.8/comptime1.8/Tvector
60      ./bigloo1.8/comptime1.8/Eval
81      ./bigloo1.8/comptime1.8/Tstruct
56      ./bigloo1.8/comptime1.8/Callcc
36      ./bigloo1.8/comptime1.8/Lifext
40      ./bigloo1.8/comptime1.8/Fail
./bigloo1.8/comptime1.8/Reduce
…

Possiamo dare in pasto l'output a sort con du -S | sort ma non funziona, poichè otteniamo una sorpresa come questa:


[root@guardian /tmp]# du -S | sort
187     ./bigloo1.8/comptime1.8/Reduce
332     ./bigloo1.8/comptime1.8/Cfa
36      ./bigloo1.8/comptime1.8/Lifext
394     ./bigloo1.8/comptime1.8/Integrate
40      ./bigloo1.8/comptime1.8/Fail
450     ./bigloo1.8/comptime1.8/Cgen
56      ./bigloo1.8/comptime1.8/Callcc
60      ./bigloo1.8/comptime1.8/Eval
81      ./bigloo1.8/comptime1.8/Tstruct
./bigloo1.8/comptime1.8/Tvector
…

Che cosa è successo? Semplice, l'ordinamento alfabetico fa si che l'output sia ordinato come 332 36 394! Il problema è che i numeri dovrebbero venir stampati come 00036, 00332, 00394, … Ma in Unix, modificare l'output di un comando prima di darlo in pasto ad un altro è la norma. In questo caso possiamo risolvere il problema riformattando l'output di du con awk. La soluzione del problema è dunque:


[root@guardian /tmp]# du -S \
>| awk '{ printf "%05d %s\n", $1, $2 }' \
>| sort -r | head
01846 ./guile-src/libguile
01433 ./lout.3.06/font
01208 ./lout.3.06
01141 ./guile-src/slib
01017 ./bigloo1.8/documentation
00798 ./lout.3.06/doc/expert
00766 ./bigloo1.8/runtime1.8/.Olib/Ieee
00762 ./siod
00725 ./bigloo1.8/runtime1.8/Gc
00670 ./bigloo1.8/runtime1.8/.Olib_u/Eval

L'aspetto cruciale in questo discorso è che il comando awk si aspetta che l'output sia costituito da righe, e che in ogni riga ci siano dei campi separati da una sequenza di spazi. Awk infatti processa riga per riga, e mette i valori dei campi nelle variabili $1, $2, $3…. Poi su queste variabili vengono eseguite semplici operazioni. Il comando du, come pure mount o ls producono l'output proprio nel formato che si aspetta awk. Questo è il segreto della programmazione di shell: tutto è rappersentato come testo, e il testo viene mantenuto nel formato il più semplice e gestibile possibile; la programmazione Unix è elaborazione di dati in formato testo.


ePrometeus s.r.l. - Web Software House & Open Source System Integrator
MILANO - SAN BENEDETTO DEL TRONTO(AP)
Contatti: info@eprometeus.com