Molti termini informatici hanno, non a caso, significati che sono direttamente correlati a quelli delle rispettive parole d'uso comune.
Il "kernel" di un sistema operativo è il nucleo, la parte interna, il nocciolo, quello, in termini informatici, che si occupa di lavorare a basso livello e gestire l'hardware e le sue risorse, la "shell", al contrario, è il guscio, la conchiglia, la parte esterna, quella a contatto con il mondo esterno, l'utilizzatore di un computer.
La shell è quindi l'interfaccia (testuale) tramite la quale l'utente può operare ed interagire con il sistema.
La shell, tecnicamente, è un normale programma che interpreta ed esegue i comandi dell'utente (viene chiamata anche Command Interpreter) permettendogli di eseguire altri programmi che accedono alle risorse hardware della macchina tramite le chiamate di sistema offerte dal kernel.
Su un sistema Unix la shell è fondamentale per moltissime attività , che vanno oltre la semplice interattività con l'utente, avendo diverse modalità funzionali:
- USO INTERATTIVO, il sistema attende i comandi digitati dall'utente, che possono redirezionare input ed output, è quello che normalmente si utilizza dopo il login e a cui ci si riferisce quando si parla di usare una shell;
- CONFIGURAZIONE della propria sessione, con cui definire variabili e parametri che vengono utilizzati in ogni interazione dell'utente con la macchina, viene fatto negli script di inizializzazione;
- PROGRAMMAZIONE utilizzando comandi di sistema e funzionalità della shell è possibile realizzare piccoli programmi (script shell) in grado di automatizzare operazioni e reagire ad eventi.
Esistono diverse varietà di shell, hanno sostanzialmente la stessa funzione ma si differenziano per funzionalità e, in parte, sintassi dei loro comandi interni. Fra le shell più diffuse segnaliamo la Bourne Shell (sh
), la Korn Shell (ksh
), la C Shell (csh
) e la Bourne Again Shell (bash
), sviluppata dal progetto GNU, rilasciata con licenza GPL e particolarmente comune su sistemi Linux.
In linea con la natura multiforme e variegata di Unix, esistono molteplici shell, ognuna delle quali presenta caratteristiche e peculiarità proprie.
sh - Bourne shell, è disponibile su qualsiasi ambiente UNIX, quindi è la più utilizzata per creare script shell compatibili e cross-platform.
csh - C shell, prende il nome dal linguaggio di programmazione, ovviamente le funzionalità di tale shell derivano in modo diretto dal C.
bash - Bourne Again Shell. Una delle ultime nate, offre le stesse capacità della C shell, con l'aggiunta di alcune funzionalità come l'history dei comandi e la TABcompletion. E' una componente del progetto GNU come, come molti altri programmi, vengono ormai usati su altri Unix, anche commerciali.
ksh - Korn shell. Largamente diffusa è compatibile con la sh sulla parte di scripting ed ha tutte le funzionalità di interazione della csh.
tcsh - E' un'evoluzione della csh, con cui mantiene piena compatibilità e introduce feature come command line editing e name completion.
rsh - Restricted Bourne shell (da non confondere con l'omonimo comando). Una shelle con funzionlità minime ed essenziali.
jsh - Bourne Shell con Job control.
dtksh - Desktop Korn Shell.
rksh - Restricted Korn Shell.
Bash acronimo di Bourne Again Shell, è la shell di gran lunga più utilizzata in ambiente Linux. E' un componente chiave del progetto GNU e rimane disponibile su ogni Unix.
Alcune sue caratteristiche (presenti anche in altre shell):
- Possibilità di editare la command line
- TAB completion dei comandi
- Possibilità di definire alias
- History infinita dei comandi inseriti
- Funzionalità di scripting, funzioni condizionali e di ciclo.
- Possibilità di definire funzioni
- Possibilità di gestire array indicizzati di dimensioni infinite
- Gestione e controllo dei job
- Espressioni aritmetiche
- Caratteri jolly (metacaratteri) nella gestione dei nomi di file
L'uso e la pratica della bash sono l'unico vero modo per conoscerla e approfondirne le molteplici caratteristiche.
Sui sistemi Linux viene lanciata automaticamente dopo il login, alternativamente basta scrivere bash (trovandosi in un'altra shell) per eseguirla.
La bash presenta una serie di funzionalità molto pratiche che è fondamentale conoscere ed utilizzare regolarmente, in quanto rendono il suo utilizzo molto più comodo e rapido.
Tutte queste funzionalità di base vanno praticate direttamente più che lette o studiate.
Si invita il lettore quindi ad aprirsi una shell e provare "sul campo" quanto segue.
TAB
Il tasto TAB è fondamentale quando su usa la bash: permette l'autocompletamento di comandi o nomi di file e directory. Abituarsi a premerlo uno o due volte in rapida successione per completare automaticamente un comando che si sta digitando o visualizzare tutti i comandi possibili che iniziano con le lettere inserite prima di "TABbare".
Oltre a velocizzare l'inserimento di comandi permette di essere certi della loro sintassi o della correttezza di nomi di file e directory inseriti.
FRECCIA SU - FRECCIA GIU
Altri tasti da usare spesso. Premendoli è possibile spostarsi nella history dei comandi digitati precedentemente nella shell. E' comodissimo in molte occasione e permette di risparmiare tempo e di fare velocemente "prove e riprove" di comandi dati.
FRECCIA DESTRA - FRECCIA SINISTRA
Permettono di muoversi all'interno della riga di comando corrente per modificarla o inserire del testo. Utili, per esempio, quando si deve cambiare leggeremente una riga di comando inserita precedentemente (e richiamata con FRECCIA SU).
SHIFT + FRECCIA SU - SHIFT + FRECCIA GIU
Permette di visualizzare l'output della shell che ormai non è più visibile nella schermata corrente. In pratica si scrolla verticalmente, di una riga alla volta, il testo visualizzato nella sessione corrente.
SHIFT + PAGINA SU - SHIFT + PAGINA GIU
Ottiene lo stesso effetto più rapidamente, eseguendo lo scroll di intere pagine alla volta invece che di singole righe.
Funzionalità della bash che permette di ri-eseguire un comando precedentemente lanciato e presente nella history.
E' possibile specificare un numero, per indicare una entry nella history, o una stringa, che permette di eseguire l'ultimo comando dato che inizia con la stringa indicata.
Tecnicamente definito event designator !
, si occupa di recuperare una entry nella history di Bash in base alla stringa o al numero passati come "parametro":
root@Joker:/home/homer/python# ls -l hello*
-rw-r--r-- 1 homer users 48 Jun 9 14:30 hello.py
-rw-r--r-- 1 homer users 70 Jun 9 15:33 hello2.py
root@Joker:/home/homer/python# history
1 ls -l hello*
2 history
root@Joker:/home/homer/python# !1
ls -l hello*
-rw-r--r-- 1 homer users 48 Jun 9 14:30 hello.py
-rw-r--r-- 1 homer users 70 Jun 9 15:33 hello2.py
Viene indicato il numero 1 (UNO) e si esegue la entry numero Uno nella history
root@Joker:/home/homer/python# !l
ls -l hello*
-rw-r--r-- 1 homer users 48 Jun 9 14:30 hello.py
-rw-r--r-- 1 homer users 70 Jun 9 15:33 hello2.py
Viene indicata la lettera l (ELLE) e si esegue l'ultimo comando presente nella history che inizia con Elle
Tutto questo è piuttosto utile per recuperare comandi complessi inseriti in precedenza, evitando di riscriverli completamente.
La shell è presente in ogni Unix, ma anche su Windows si può ricostruire il propro mondo shell.
Il vecchio DOS e il più recente prompt dei comandi Windows, seppur simili come aspetto (command line interpreter testuale) e in parte come funzionalità non danno un'idea completa di cosa è possibile fare con una shell evoluta o quantomeno Bourne-like.
E' possibile sentirne l'ebbrezza con l'ottimo CYGWIN, che è molto di più di una shell, è un vero e proprio ambiente Unix, con tanto di compilatore, disponibile sotto Windows.
Può essere molto comodo per utilizzare comandi comuni e pratici tipici di un sistema Unix direttamente da una finestra Windows.
E' possibile creare dei semplici comandi ridondanti, per lanciare n volte un determinato programma.
Tutto si basa sul costrutto for do
del linguaggio di scripting della bash, che permette di iterare più volte un determinato compito.
Ad esempio volendo scaricare diverse immagini iso, sarebbe necessario lanciare più comandi simili:
ftp.debian.it\debian-cd1.iso
...
ftp.debian.it\debian-cd7.iso
E' possibile automatizzare il lavoro mediante un' unica command line:
for n in `seq 1 7`; do proz ftp.debian.it\debian-cd$n.iso; done
Scaricaricherà in automatico i 7 cd consecutivamente mediante il downloader accelerator prozilla
Visualizzare il calendario da shell.
Anche nello spartano ambiente della shell, è possibile all'occorenza visualizzare un calendario. Questo grazie al comando cal
:
[azitti@pegasus azitti]$ cal
February 2005
Su Mo Tu We Th Fr Sa
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28
[azitti@pegasus azitti]$ cal -m 12 2004
Viene indicato a cal di stampare il 12° mese (-m 12) dell'anno 2004
December 2004
Mo Tu We Th Fr Sa Su
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Il comando invocato senza parametri, visualizza il mese corrente, in alternativa è possibile visualizzare mesi passati, futuri, o anche l'intero anno.
Una breve panoramica di comandi comodi da usare da shell
- Spegnere il PC da riga di comando
# poweroff
- Riavviare il PC da riga di comando
# reboot
- Passare da modalità grafica a modalità testuale
# init 3
Quindi autenticarsi (login+password)
- Passare da modalità testuale a modalità grafica
# init 5
Quindi autenticarsi (login+password)
- Passare da console grafica a console testuale
Premere CTRL+ALT+F5 (o F1 o F2 o F3 o F4 o F6)
Quindi autenticarsi (login+password)
- Per tornare dalla console testuale a quella grafica
Premere ALT+F7
- Per visualizzare il percorso (path) in cui vi trovate attualmente nella shell che state usando digitate:
# pwd
Albe
La ricorsione in bash (esempio pratico di un fork bomb).
NDR. Da provare solo su sistemi che si vogliono far inchiodare.
$ :(){ :|:&};:
dove:
:()
definisce una funzione chiamata ":"
il cui body è
{
: chiama se stessa
| in pipe
: a se stessa
& in background
};
e infine
:
la chiamata alla funzione sopradescritta
La tab completion è quella caratteristica che permette di velocizzare l'inserimento dei dati via command line, grazie all'utilizzo del tasto tabulatore.
Su Windows XP è abilitata di default, ma questa feature è presente anche su sistemi Windows 2000. E' possibile utilizzarla eseguendo modificando due chiavi del registro di sistema.
Qualora si voglia abilitare la tab completion per tutti gli utenti è necessario modificare le chiavi seguenti, impostandone il valore a 09 esadecimale:
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\CompletionChar
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\PathCompletionChar
Nel caso invece si voglia abilitare la feature solo per l'utente corrente le key da modificare sono:
HKEY_CURRENT_USER\Software\Microsoft\Command Processor\CompletionChar
HKEY_CURRENT_USER\Software\Microsoft\Command Processor\PathCompletionChar
A seconda del tipo di modifica da attuare sarà necessario avere i relativi permessi per la modifica del Registry.
Spesso capita di sbagliare un nome di file (magari lunghissimo) o un comando o una flag e di scriverlo maiuscolo invece di minuscolo o viceversa (magari per disattenzione si aveva lasciato capslock attivo).
Niente paura:
ALT + U
davanti alla parola sbagliata e, voilà, diventa maiuscola (U sta per uppercase, cioè maiuscolo)
ALT + L
davanti alla parola sbagliata e, voilà, diventa minuscola (L sta per lowercase, cioè minuscolo)
Vediamo come scrivere un ciclo for usando la notazione del C.
Quando si vuole ripetere un istruzione, o una serie di istruzioni per un determinato numero di volte, si può ricorrere ad un ciclo. In particolare, se conosciamo a priori il numero esatto di ripetizioni, possiamo agevolemente usare un ciclo for tutto in stile C.
Esempio:
#!/bin/bash
for((i=0; i<10; i++)); do
touch file$i.log
done
Cosa fa questo script?
Crea 10 file che si chiamano file0.log, file1.log... ecc.
Come funziona?
All'interno del ciclo for ci sono 3 istruzioni:
i=0; questa è l'inizializzazione della variabile i. Tale istruzione verrà eseguita solo al primo passaggio dentro il ciclo
i<10; questa è la condizione di permanenza nel ciclo. Si dice che il for esce per falso, ciò significa che il ciclo finirà quando i sarà maggiore o uguale 10. Ovviamente sono possibili espressioni più complesse.
i++; questa istruzione non fa altro che incrementare di 1 il valore di i. Viene eseguita ogni volta che si entra nel ciclo ad esclusione della prima volta.
A volte potrebbe essere utile salvare una sessione di shell, magari per riguardare tutte le operazioni compiute con calma o per postare un howto... .
Il modo più semplice di farlo è di usare il comando script, presente in quasi tutte le distribuzioni.
Basta indicare il nome del file in cui si vuole salvare la sessione:
pmate@pc:~$ script miasessione.log
Una volta lanciato il comando tutto quello che si farà sulla shell verrà "registrato" nel file miasessione.log fino a che non verrà impartito il comando
pmate@pc:~$ exit
Il file miasessione.log conterrà dunque i comandi impartiti, l'output che questi genereranno e il timestamp indicante l'inizio e la fine della registrazione.
Facciamo un esempio:
pmate@pc:~$ script miasessione.log
Script started on mar 18 mar 2008 01:44:23 CET
pmate@pc:~$ uname -a
Linux debian-laptop 2.6.22-3-686 #1 SMP Sun Feb 10 20:20:49 UTC 2008 i686 GNU/Linux
pmate@pc:~$ exit
exit
Script done on mar 18 mar 2008 01:44:38 CET
Se adesso diamo un bel cat:
pmate@pc:~$ cat miasessione.log
Script started on mar 18 mar 2008 01:44:23 CET
$ uname -a
Linux debian-laptop 2.6.22-3-686 #1 SMP Sun Feb 10 20:20:49 UTC 2008 i686 GNU/Linux
$ exit
exit
Per "pulire" il contenuto di miasessione.log dai caratteri di escape, che con il comando cat non vengono visualizzati ma con gli editor di testo (ad esempio vim) disturbano non poco la visualizzazione, basta dare:
pmate@pc:~$ col -bx <miasessione.log >miasessione.txt