Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
FONDAMENTI DEI SISTEMI OPERATIVI<br />
Appunti dalle esercitazioni del laboratorio di GNU/Linux<br />
(Ing. Silvia Giannini)<br />
Anno Accademico 2012-2013
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
Premessa<br />
La presente dispensa contiene una descrizione dei comandi di <strong>shell</strong> <strong>Bash</strong> presentati a lezione<br />
nell’ambito delle esercitazioni su sistemi operativi GNU/Linux per il corso di Fondamenti dei<br />
Sistemi Operativi, tenuto dal Prof. Giacomo Piscitelli nei corsi di laurea di Ingegneria<br />
Informatica e dell’Automazione ed Ingegneria Elettronica e delle Telecomunicazioni (A.A.<br />
2012-13).<br />
Parte del contenuto è tratto dalle slide del corso di <strong>Lab</strong>oratorio di Sistemi Operativi<br />
(distribuite nei termini della licenza Creative Commons “Attribuzione/Condividi allo stesso<br />
modo 2.5” http://creativecommons.org/licenses/by-sa/2.5/it/legalcode), tenuto dal Dott.<br />
Gennaro Oliva presso l’Università degli Studi di Napoli Federico II nell’A.A. 2010-11.<br />
Saranno apprezzate e benvenute le segnalazioni di errori, imprecisioni ed omissioni (mail to<br />
s.giannini@deemail.poliba.it).<br />
Tale dispensa non è da considerarsi esaustiva sugli argomenti affrontati a lezione. Per ulteriori<br />
approfondimenti si rimanda a "Linux e la <strong>shell</strong> <strong>Bash</strong>"<br />
(http://sisinflab.poliba.it/giannini/SO/Linux_e_la_<strong>shell</strong>_<strong>Bash</strong>.pdf)<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 2
Indice<br />
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
<strong>Comandi</strong> di help .....................................................................................................................6<br />
man ....................................................................................................................................6<br />
Il file system ...........................................................................................................................8<br />
pwd ....................................................................................................................................8<br />
ls ........................................................................................................................................8<br />
Protezione di file e directory ...........................................................................................9<br />
cd ..................................................................................................................................... 10<br />
cp ..................................................................................................................................... 10<br />
mkdir ................................................................................................................................ 11<br />
mv .................................................................................................................................... 11<br />
rm ..................................................................................................................................... 11<br />
rmdir ................................................................................................................................ 11<br />
stat .................................................................................................................................... 12<br />
touch ................................................................................................................................ 12<br />
Manipolazione dei permessi .............................................................................................. 13<br />
chown ............................................................................................................................... 13<br />
chgrp ................................................................................................................................ 13<br />
chmod............................................................................................................................... 13<br />
Link .................................................................................................................................. 13<br />
Hard link .......................................................................................................................... 14<br />
Soft link o symbolic link ................................................................................................... 14<br />
Altri comandi di base ............................................................................................................ 15<br />
alias/unalias ...................................................................................................................... 15<br />
echo .................................................................................................................................. 15<br />
date ................................................................................................................................... 15<br />
which ................................................................................................................................ 15<br />
Caratteri speciali di <strong>shell</strong>....................................................................................................... 16<br />
1. File globbing................................................................................................................. 16<br />
2. Espansione della <strong>shell</strong> ................................................................................................... 16<br />
3. Regole di quoting .......................................................................................................... 16<br />
Espressioni Regolari ............................................................................................................. 17<br />
Sintassi delle espressioni regolari ...................................................................................... 17<br />
Caratteri speciali della <strong>shell</strong> ed espressioni regolari ........................................................... 19<br />
Caratteri speciali per le espressioni regolari ................................................................ 19<br />
Operatori di ripetizione ..................................................................................................... 19<br />
Regole di precedenza degli operatori ................................................................................ 20<br />
<strong>Comandi</strong> di ricerca di stringhe .............................................................................................. 20<br />
grep .................................................................................................................................. 20<br />
Gestione utenti e gruppi ........................................................................................................ 24<br />
Gruppi di utenti ................................................................................................................ 24<br />
groupadd .......................................................................................................................... 24<br />
groupdel ........................................................................................................................... 24<br />
groupmod ......................................................................................................................... 24<br />
useradd ............................................................................................................................. 25<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 3
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
passwd .............................................................................................................................. 25<br />
userdel .............................................................................................................................. 26<br />
usermod ............................................................................................................................ 26<br />
su (substitute user) ............................................................................................................ 27<br />
<strong>Comandi</strong> informativi ............................................................................................................ 27<br />
id ...................................................................................................................................... 27<br />
whoami ............................................................................................................................. 28<br />
who .................................................................................................................................. 28<br />
groups............................................................................................................................... 28<br />
last .................................................................................................................................... 28<br />
Variabili ............................................................................................................................... 29<br />
Definizione ....................................................................................................................... 29<br />
Variabili d'ambiente ......................................................................................................... 29<br />
printenv ............................................................................................................................ 29<br />
export ............................................................................................................................... 30<br />
set/unset............................................................................................................................ 30<br />
Visualizzazione ed editing di file .......................................................................................... 31<br />
cat..................................................................................................................................... 31<br />
file .................................................................................................................................... 31<br />
less (more) ........................................................................................................................ 31<br />
Canali di comunicazione e ridirezione .................................................................................. 32<br />
Operatori di ridirezione dello standard output ................................................................... 32<br />
Operatori di ridirezione dello standard error ...................................................................... 32<br />
Operatori di ridirezione dello standard input ..................................................................... 32<br />
Operatore di pipeline ........................................................................................................ 33<br />
Liste di comandi ................................................................................................................... 33<br />
sequenza ........................................................................................................................... 33<br />
concorrenza ...................................................................................................................... 34<br />
condizione ........................................................................................................................ 34<br />
esclusione ......................................................................................................................... 34<br />
Exit status di liste di comandi ........................................................................................... 34<br />
Script BASH ........................................................................................................................ 34<br />
Filtri e programmi di utilità generica..................................................................................... 35<br />
sort ................................................................................................................................... 35<br />
wc..................................................................................................................................... 36<br />
head .................................................................................................................................. 36<br />
tail .................................................................................................................................... 36<br />
uniq .................................................................................................................................. 37<br />
cut .................................................................................................................................... 37<br />
diff ................................................................................................................................... 38<br />
Gestione dei processi ............................................................................................................ 39<br />
Avvio del sistema .............................................................................................................. 39<br />
Runlevel ........................................................................................................................... 39<br />
shutdown .......................................................................................................................... 40<br />
Controllo dei processi ....................................................................................................... 40<br />
ps ...................................................................................................................................... 41<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 4
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
pstree ................................................................................................................................ 43<br />
top .................................................................................................................................... 43<br />
Background e foreground ............................................................................................. 44<br />
yes .................................................................................................................................... 44<br />
sleep ................................................................................................................................. 44<br />
wait .................................................................................................................................. 44<br />
jobs ................................................................................................................................... 44<br />
fg ...................................................................................................................................... 45<br />
bg ..................................................................................................................................... 45<br />
Segnali ............................................................................................................................. 45<br />
kill .................................................................................................................................... 46<br />
pkill .................................................................................................................................. 47<br />
killall ................................................................................................................................ 47<br />
Terminazione di un processo ............................................................................................ 47<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 5
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
<strong>Comandi</strong> di help<br />
man<br />
Il comando man (manual) fornisce informazioni su qualsiasi comando, visualizzandone la pagina di manuale<br />
relativa.<br />
Il manuale è suddiviso in pagine logiche che corrispondono ad una sezione. Ogni sezione si riferisce ad un<br />
insieme di argomenti logicamente affini.<br />
Le pagine di manuale di un sistema UNIX sono raggruppate in 8 sezioni:<br />
1) programmi eseguibili o comandi di <strong>shell</strong> (ls, vi, ...);<br />
2) system call (open, write, fork, ...);<br />
3) funzioni di libreria (printf, scanf, …);<br />
4) file speciali (/dev/null, /dev/mouse, ...);<br />
5) formati di file (/etc/passwd, /etc/hosts, …);<br />
6) giochi (fortune, ...);<br />
7) protocolli, convenzioni, panoramiche, varie (tcp, boot, ... );<br />
8) comandi per la gestione del sistema (iptables, mkfs, ...).<br />
SINTASSI: $ man [opzioni] comando<br />
$ man man<br />
All'interno di una pagina di manuale ci si può muovere con i tasti direzione: su, giù, pg su, pg giù. Si esce dalla<br />
visualizzazione premendo q (quit). Si può ricercare una stringa digitando /stringa e se ne visualizzano le<br />
occorrenze premendo n (occorrenza successiva) oppure N (occorrenza precedente).<br />
La struttura della documentazione dei comandi è simile per ogni comando e segue il paradigma LDP (Linux<br />
Documentation Project). All'interno di una pagina di manuale ci sono varie sottosezioni. Quelle convenzionali<br />
sono: NAME, SYNOPSIS, CONFIGURATION, DESCRIPTION, OPTIONS, EXIT STATUS, RETURN<br />
VALUE, ERRORS, ENVIRONMENT, FILES, VERSIONS, CONFORMING TO, NOTES, BUGS, EXAMPLE,<br />
AUTHORS, SEE ALSO.<br />
Di particolare rilevanza:<br />
NAME: nome del comando e relativo commento<br />
SYNOPSIS: sintassi del comando<br />
DESCRIPTION: descrizione dettagliata del comando<br />
OPTIONS: flag attribuibili al comando<br />
Opzioni:<br />
-f Mostra NAME (con session) e relativo commento (equivale a SINTASSI: $ whatis comando)<br />
-k Cerca nel NAME e nel commento del man di tutti i comandi il pattern (comando) in argomento.<br />
Risponde col NAME del comando e con il commento associato (equivale a SINTASSI: $ apropos comando)<br />
-L Consente di visualizzare il manuale nella traduzione richiesta, se disponibile.<br />
$ man -L it man<br />
$ man -L en man<br />
L'argomento del comando man viene ricercato all'interno delle sezioni in ordine crescente. Alla prima<br />
corrispondenza trovata, viene visualizzata la pagina di manuale individuata. Alcune parole chiave possono essere<br />
presenti in più sezioni, quindi per visualizzare il manuale di una sezione specifica bisogna anteporre come<br />
opzione il numero della sezione (preceduto o meno dal flag -s).<br />
Esempi.<br />
- La parola write corrisponde almeno a due pagine di manuale: (1) il comando write per comunicare con gli<br />
utenti; (2) la system call write per l'I/O a basso livello.<br />
Per visualizzare la pagina della system call usiamo: $ man 2 write<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 6
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
- $ man -s1 chmod (Mostra la prima sessione)<br />
$ man -s2 chmod (Mostra la seconda sessione)<br />
In maniera alternativa, è possibile utilizzare<br />
SINTASSI: $ comando --help Accede direttamente alla sottosezione relativa alla descrizione delle options.<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 7
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
Il file system<br />
Il file system di Unix ha un'organizzazione gerarchica ad albero, la cui radice (root) è una directory identificata<br />
dal carattere /. Alcune sottodirectory della root directory sono comuni a tutti i sistemi UNIX.<br />
bin: programmi binari (built-in) essenziali utilizzabili da tutti gli utenti<br />
sbin: (superuser bin) programmi binari essenziali per l'amministrazione del sistema<br />
boot: file necessari all'avvio del sistema quali il kernel ed i driver<br />
dev: file speciali associati a dispositivi hardware<br />
etc: file di configurazione<br />
home: home directory degli utenti che hanno un account sulla macchina<br />
root: home directory del root user<br />
tmp: file temporanei<br />
usr: file read-only<br />
var: file che il sistema scrive durante l'esecuzione (log, spool, cache, ...)<br />
Per i sistemi Linux i nomi delle directory e le loro funzioni sono stabilite dal Filesystem Hierarchy Standard<br />
(FHS).<br />
I nomi di file e directory possono essere composti da qualsiasi sequenza di caratteri eccetto /. E' buona prassi<br />
limitarsi nell'utilizzo degli spazi. Ogni directory contiene 2 directory speciali: ., che corrisponde alla directory<br />
stessa; .., che corrisponde alla directory padre (la directory padre di / è / stessa).<br />
La struttura ad albero consente di identificare univocamente un elemento del file system mediante il percorso che<br />
va dalla root directory / al file stesso. Questo percorso viene detto pathname. Nel pathname tutte le directory del<br />
percorso vengono separate dal carattere /. Un pathname che inizia con il carattere / viene detto assoluto, parte<br />
dalla root directory ed arriva ad un elemento del filesystem. Un pathname che inizia senza il carattere /, parte da<br />
una directory del file system e viene detto relativo.<br />
pwd<br />
Il comando pwd (print working directory) mostra sullo standard output il percorso completo (pathname assoluto)<br />
della directory di lavoro corrente.<br />
SINTASSI: $ pwd<br />
user@ubuntu:~$ pwd<br />
/home/user<br />
ls<br />
Il comano ls (list) lista il contenuto di una directory in ordine alfabetico (in assenza del path in argomento lista il<br />
contenuto della current working directory - cwd).<br />
SINTASSI: $ ls [opzioni] [path]<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 8
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
Opzioni:<br />
-a (all) Mostra anche i file nascosti (tutti i file che iniziano con il carattere '.')<br />
-F Associa un identificatore per ogni tipo di file in coda al nome (@ link simbolico; * eseguibile; /<br />
directory; | FIFO; = socket)<br />
-t Ordina i file per data di modifica, dal più recente<br />
-u Ordina i file per data di ultimo accesso, dal più recente<br />
-r Inverte l'ordine alfabetico di visualizzazione<br />
-R Visualizza in modo ricorsivo il contenuto delle sottodirectory<br />
-1 Visualizza l'elenco in un'unica colonna<br />
-Q Circonda i nomi dei file con le virgolette (utile in caso di nomi di file che contengono spazi)<br />
-i Visualizza l'#i-node del file.<br />
-l Mostra informazioni dettagliate sui file contenuti nella directory in maniera tabellare:<br />
[Access Control List] [numero di link al file] [utente] [gruppo] [dimensione in byte] [ultimo accesso]<br />
[nome simbolico file]<br />
Protezione di file e directory<br />
Unix è un sistema multi utente e necessita di meccanismi di protezione di file e directory per consentire ad ogni<br />
utente di preservare i propri dati dall'accesso da parte di altri utenti. Ogni file ha un proprietario e un gruppo di<br />
appartenenza. L'amministratore può modificare, assieme al proprietario, i diritti d'accesso.<br />
Al file sono associate protezioni per tre tipi di accesso:<br />
a) Accesso in lettura identificato dalla lettera “r” (read)<br />
b) Accesso in scrittura identificato dalla lettera “w” (write)<br />
c) Accesso in esecuzione identificato dalla lettera “x” (execute)<br />
Le protezioni possono essere applicate a 3 classi di utenti:<br />
1. il proprietario del file (user)<br />
2. il gruppo a cui appartiene il file (group)<br />
3. tutti gli altri utenti (others)<br />
L'Access Control List (ACL) è una sequenza di 10 caratteri. Il primo carattere rappresenta il tipo di file:<br />
d directory (contiene nomi di file e puntatori ad i-node)<br />
l link simbolico (puntatore a file)<br />
- file ordinario o regolare (contengono dati, senza distinzione tra file binari o di testo)<br />
b file speciale a blocchi (file speciale che fornisce un'interfaccia bufferizzata a blocchi di lunghezza<br />
fissa per l'I/O da dispositivi di memorizzazione quali hard disk, cdrom, floppy ...)<br />
c file speciale a caratteri (file speciale che fornisce un'interfaccia non bufferizzata con blocchi di<br />
lunghezza variabile a dispositivi quali schede audio, terminali, porte seriali, ...)<br />
p file FIFO o pipe con nome (tipo di file destinato alla comunicazione iterprocesso su una stessa<br />
macchina)<br />
s socket (file utilizzato per la comunicazione tra due processi anche su rete)<br />
Gli altri 9 caratteri vanno interpretati a gruppi di tre:<br />
AuBuCu AgBgCg AoBoCo<br />
A: permesso di lettura (r o -)<br />
B: permesso di scrittura (w o -)<br />
C: permesso di esecuzione (x o -)<br />
per lo user owner (u); per il group owner (g); per gli others (o) ovvero il resto del mondo.<br />
Esempio di ACL: l rw- rw- r--<br />
Si tratta di un link simbolico. L'utente proprietario ha permessi di lettura e scrittura, non di esecuzione; gli utenti<br />
appartenenti al gruppo del proprietario hanno diritto di lettura e scrittura, non di esecuzione; il resto del mondo<br />
ha solo diritto di esecuzione.<br />
Nel caso di directory, i tre tipi di permesso assumono il seguente significato:<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 9
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
r Visualizzare il contenuto della directory (il list è una lettura)<br />
w Scrivere all'interno della directory (rinomina, modifica, rimozione)<br />
x Attraversare una directory, ovvero utilizzare il nome della directory per accedere ad un qualsiasi file<br />
contenuto nel sottoalbero di cui è radice. Assegnare un premesso di esecuzione ad una directory<br />
equivale a permettere la navigazione dell'albero. Se chiedo il list del contenuto di una cartella che non<br />
posso eseguire il sistema comunica permission denied. Negli altri casi il permesso di esecuzione<br />
esiste solitamente solo per file ordinari.<br />
E' d'uso fare una maschera in forma ottale dell'ACL, escluso il primo carattere. I 9 valori possono essere<br />
interpretati come bit (0: permesso negato; 1: permesso concesso) e considerati a gruppi di 3 (8 combinazioni per<br />
ciascun terzetto).<br />
Esempi:<br />
110 110 100 = 664 (dall'esempio precedente)<br />
755 = 111 101 101 ovvero rwx r-w r-w<br />
640 = 110 100 000 ovvero rw- r-- ---<br />
cd<br />
Il comando cd (change directory) cambia la cwd corrente con quella specificata.<br />
SINTASSI: $ cd [path]<br />
Utilizzi particolari:<br />
cd (Torna alla homedir dell'utente loggato: equivale a cd ~)<br />
cd - (Torna alla directory precedentemente referenziata, memorizzata nella variabile d'ambiente<br />
OLDPWD)<br />
cd . (Porta nella cwd)<br />
cd .. (Porta nella directory padre della cwd)<br />
$ cd /<br />
$ cd /usr/bin<br />
Esercizi<br />
1. Visualizzate la pagina di manuale del comando ls.<br />
2. Cercate la stringa “long” per leggere la sezione relativa all'opzione -l.<br />
3. Cercate la stringa “all” per leggere la sezione relativa all'opzione -a.<br />
4. Spostatevi nella directory /usr/bin .<br />
5. Visualizzatene il contenuto.<br />
6. Tornate nella vostra home directory.<br />
cp<br />
Il comando cp (copy) copia il file (o una directory vuota) dal percorso di partenza a quello di destinazione. Se il<br />
file di destinazione non esiste viene creato, viceversa si rischia la sovrascrittura. La copia di cartelle non vuote va<br />
effettuata in maniera ricorsiva.<br />
SINTASSI: $ cp [opzioni] [path/]fileOrigine [path/]fileDest<br />
Opzioni:<br />
-f Forza la sovrascrittura<br />
-i Richiede interattivamente la conferma di sovrascrittura<br />
-p Mantiene le caratteristiche del file sorgente compresa la data e l'ora di referenziazione<br />
-R Copia ricorsiva<br />
-v Verbose mode<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 10
Esempi:<br />
$ cp esempio esempio.bak<br />
$ cp -i esempio2 esempio.bak<br />
$ cp -Rv dir/dir1 silviax<br />
mkdir<br />
Il comando mkdir (make directory), crea una directory.<br />
SINTASSI: $ mkdir [opzioni] [path/]nomeDir<br />
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
Opzioni:<br />
-m ACL Crea una directory specificando l'ACL<br />
-v Verbose Mode: mostra sullo standard output le operazioni eseguite<br />
Esempi:<br />
$ mkdir prova<br />
$mkdir prova1 prova2<br />
$ mkdir prova1/prova11 /home/silvia/prova/prova2<br />
$ mkdir -m 766 prova3<br />
Come verificate che la creazione sia andata a buon fine?<br />
$ mkdir -vm 766 provaV<br />
mv<br />
Il comando mv (move), sposta (cut and paste/rename) file o directory da un percorso di partenza ad uno di<br />
destinazione.<br />
SINTASSI: $ mv [opzioni] [path/]fileOrigine [path/]fileDest<br />
Opzioni:<br />
-f Forza la sovrascrittura<br />
-i Richiede interattivamente la conferma di sovrascrittura<br />
-v Verbose mode<br />
Esempi:<br />
$mv file1 file2 (rinomina file 1 come file2 eventualmente sovrascrivendolo)<br />
$mv file1 dirA (sposta file1 in dirA)<br />
$mv dirA file1 (non concesso se file1 è un file esistente)<br />
$mv dirA dirB (sposta dirA in dirB o rinomina dirA in dirB, se dirB non esiste)<br />
rm<br />
Il comando rm (remove file), rimuove un file (o una directory in manera ricorsiva se non vuota).<br />
SINTASSI: rm [opzioni] nomeFile<br />
Opzioni:<br />
-R Cancellazione ricorsiva del contenuto di una directory e della directory stessa, se non vuota<br />
-v Verbose mode<br />
Esempi:<br />
$ rm -Rv provaFull<br />
$ rm file1<br />
rmdir<br />
Il comando rmdir (remove directory), cancella una directory. La directory dev'essere vuota.<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 11
SINTASSI: $ rmdir [opzioni] nomeDir_1 [nomeDir_n]<br />
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
Opzioni:<br />
--ignore-fail-on-non-empty Non mostra a video il messaggio di errore<br />
-v Verbose mode<br />
stat<br />
Ad ogni file sono associate una serie di informazioni o metadati, quali la dimensione, i permessi, le date di<br />
accesso e di modifica. Queste informazioni possono essere lette dal filesystem e vengono memorizzate in una<br />
struttura dati chiamata stat che contiene almeno i seguenti membri:<br />
struct stat {<br />
dev_t st_dev /*ID del device che contiene il file*/<br />
ino_t st_ino /*n.ro inode*/<br />
mode_t st_mode /*tipo di file e permessi*/<br />
nlink_t st_nlink /*numero di link al file*/<br />
uid_t st_uid /*user ID del proprietario del file*/<br />
gid_t st_gid /*group ID del proprietario del file*/<br />
dev_t st_rdev /*device ID (se il file è speciale a blocchi o a caratteri)*/<br />
off_t st_size /*dimensione del file in bytes (per file regolari, directory o link)*/<br />
time_t st_atime /*orario dell'ultimo accessoai dati*/<br />
time_t st_mtime /*orario dell'ultima modifica ai dati*/<br />
time_t st_ctime /*orario dell'ultimo cambiamento all'inode (ad esempio attraverso chmod)*/<br />
blksize_t st_blksize /*dimensione del blocco per l'oggetto (è specifica del FS, può variare da file a file)*/<br />
blkcnt_t st_blocks /*numero di blocchi allocati per l'oggetto*/<br />
}<br />
Per avere informazioni su data di creazione, accesso e modifica di un file si può utilizzare il comando<br />
SINTASSI: $ stat nomeFile)<br />
touch<br />
Aggiorna data ed ora di ultima referenziazione del file in argomento (di default cambia sia l'orario di accesso che<br />
di modifica), con l'orario corrente. Se il file non esiste, crea un file vuoto con data e ora corrente.<br />
SINTASSI: $ touch [opzioni] nomeFile<br />
Opzioni:<br />
-a Cambia l'orario di accesso<br />
-c Non crea il file, aggiorna solo la data di ultimo accesso<br />
-m Cambia l'orario di modifica<br />
Esempio:<br />
$ touch prova/touch.exe<br />
Esercizi<br />
1. All'interno della vostra home directory create 2 directory denominate “uno” e “due”.<br />
2. Copiate il file /etc/profile nella directory uno, conservandone il nome.<br />
3. Copiate il file /etc/profile nella directory due cambiandone il nome in copia-profile.<br />
4. Spostate il file profile nella directory due ed il file copia-profile nella directory uno.<br />
5. Cancellate i due file con uno stesso comando.<br />
6. Cancellate le due directory vuote.<br />
7. Verificate il funzionamento di touch per la modifica dell'orario di ultimo accesso e per la creazione di un file<br />
vuoto.<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 12
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
Manipolazione dei permessi<br />
Al momento della creazione di un file, esso appartiene all’utente che lo ha creato e assume il gruppo di<br />
quest’ultimo. Il superuser può modificare queste informazioni con i comandi:<br />
chown<br />
Il comando chown (change owner), modifica il proprietario di un file.<br />
SINTASSI: # chown newowner file1 [file2 ... fileN]<br />
chgrp<br />
Il comando chgrp (change group), modifica l'owner group di un file.<br />
SINTASSI: # chgrp newgroup file1 [file2 ... fileN]<br />
Esempio:<br />
# chown userB:groupB file1<br />
chmod<br />
Il comando chmod (change mode), consente all'utente proprietario (o al superuser) di modificare i permessi (la<br />
ACL) di file e directory.<br />
SINTASSI: $ chmod [codiceUtente±codicePermesso | formaOttale] file1 [file2 ... fileN]<br />
codiceUtente: user group other all<br />
operatore: + (aggiunge) – (rimuove);<br />
codicePermesso: read write execute.<br />
Esercizi<br />
1. Copiate il file /bin/ls nella vostra home directory specificando il pathname.<br />
2. Eliminate i permessi di esecuzione a tutti gli utenti per la copia locale.<br />
3. Ripristinate i permessi di esecuzione al solo proprietario del file.<br />
4. Create una directory “test” nella vostra home directory e copiate il file /bin/ls al suo interno<br />
5. Eliminate i permessi di esecuzione alla directory e provate a listare il contenuto. Perché non è concessa<br />
l'operazione?<br />
6. Ripristinate i vecchi permessi e cancellate con un unico comando il file all'interno della directory e la<br />
directory stessa.<br />
Link<br />
Un cilindro è organizzato in i-nodes (i-node table) e data-blocks.<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 13
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
Ad ogni file è associato un singolo ed unico i-node che memorizza la maggior parte delle informazioni restituite<br />
da stat (numero di link, dimensione, proprietario, allocazione sul disco, etc.) e i puntatori ai data block, in cui<br />
viene memorizzato il contenuto di un file. All’aumento delle dimensioni del file può corrispondere un aumento<br />
dei data block allocati per il file.<br />
Il data block di una directory viene detto directory block e contiene, per ogni file contenuto nella directory, una<br />
directory entry (#inode, filename) contenente il nome del file e il numero di i-node ad esso associato. La<br />
modifica del nome di un file viene effettuata sull'informazione memorizzata nel directory block.<br />
Un riferimento ad un file è detto link. Ogni file può avere un numero qualsiasi di link.<br />
UNIX ha due tipi di link: hard link e soft link. Entrambi possono essere creati con il comando ln.<br />
Hard link<br />
Un hard link è un puntatore all'i-node di un file. Un hard link è un elemento all’interno di una directory il cui<br />
numero di i-node corrisponde a quello di un altro file. In pratica, è possibile creare “un file” all’interno di una<br />
directory creando un puntatore ad un file già esistente. Un hard link eredita tutte le informazioni associate all'inode<br />
del file originale e non c'è più modo di distinguere tra l'hard link e il file originale.<br />
Le directory hanno un numero di link almeno pari a 2: un puntatore è memorizzato nella voce corrispondente<br />
contenuta dalla directory “padre”; un puntatore è contenuto nella stessa directory verso “.”.<br />
La maggior parte di implementazioni UNIX moderne non consente di creare ulteriori hard link a directory.<br />
Questo limite viene imposto per evitare ricorsioni infinite nel tentativo di attraversare un albero che parte da un<br />
hard link che punta alla propria directory padre. Inoltre, non è possibile effettuare un hard link con un file<br />
memorizzato su una partizione diversa da quella della directory in cui lo si vuole creare.<br />
Ogni volta che si crea un hard link ad un file, il link count per il file si incrementa di 1.<br />
Quando il comando rm riceve come argomento un hard link, il sistema decrementa il link count (nell’i-node del<br />
file) di 1. Se il link count non è 0, il sistema rimuove solo la directory entry del file cancellato. Il contenuto del<br />
file e altre directory entry per quel file (hard link) rimangono inalterati. Se il link count è 0, il sistema rimuove la<br />
directory entry per quel file, libera l’-inode del file e dealloca i data block che contenevano il file.<br />
SINTASSI: ln [opzioni] fileEsistente1 [fileEsistente2 ... fileEsistenteN] nuovoFile<br />
fileEsistenteX non può essere una directory.<br />
nuovoFile può essere una directory. In tal caso viene creato un hard link all'interno di nuovoFile a tutti i<br />
fileEsistenti indicati nel comando e i link hanno lo stesso nome dei file originari.<br />
Opzioni:<br />
-n Non crea il link se nuovoFile esistente già.<br />
Soft link o symbolic link<br />
Un soft link (o symbolic link) corrisponde ad un file che contiene, all’interno dell’unico data block ad esso<br />
associato, il percorso assoluto di un altro file. I soft link superano i limiti degli hard link in quanto consentono di:<br />
- creare collegamenti tra entità su filesystem diversi;<br />
- creare link a directory.<br />
Un soft link può essere utilizzato per creare puntatori a file o directory lasciando sempre ben chiara la distinzione<br />
tra il file originale e il link.<br />
Quando il comando rm riceve come argomento un soft link, cancella quest'ultimo e non il file a cui esso si<br />
riferisce.<br />
SINTASSI: $ ln -s pathnameAssolutofileEsistente nomeLink<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 14
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
Altri comandi di base<br />
alias/unalias<br />
L'alias è un nome alternativo dato ad una sequenza complessa<br />
SINTASSI: $ alias Visualizza tutti gli alias<br />
$ alias nomeAlias='comando' Crea un alias<br />
Esempi:<br />
$ alias al='ls -al'<br />
$ alias cp='cp -i' (impone al sistema il controllo di sovrascrittura)<br />
SINTASSI: $ unalias [opzioni] nomeAlias Distrugge l'alias nomeAlias<br />
Esempio:<br />
$ unalias al<br />
Opzioni:<br />
-a Distrugge tutti gli alias<br />
echo<br />
Stampa una stringa sullo standard output.<br />
SINTASSI: $ echo [stringa]<br />
Esempi:<br />
$ echo hello world!<br />
$ echo ~ (Mostra il percorso assoluto della home-dir dell'utente loggato, vedi sezione Espansione<br />
della <strong>shell</strong>)<br />
date<br />
Mostra la data e l'ora corrente<br />
which<br />
Stampa il path assoluto di un comando<br />
Esercizio:<br />
Trovate il path del comando whoami<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 15
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
Caratteri speciali di <strong>shell</strong><br />
Prima di eseguire un comando, la <strong>shell</strong> interpreta alcuni caratteri speciali (wildcard) sostituendoli secondo<br />
regole. Il carattere di escape \ preserva un singolo carattere dall'espansione della <strong>shell</strong> (analogo utilizzo è<br />
attribuito al simbolo di escape nelle espressioni regolari).<br />
$ echo \*<br />
1. File globbing<br />
* l'asterisco rappresenta un gruppo qualsiasi di caratteri, compreso il punto, purché il punto non si trovi all'inizio<br />
del nome<br />
$ rmdir pro* Cancella tutte le directory vuote il cui nome inizia con pro<br />
? il punto interrogativo rappresenta un unico carattere qualsiasi, compreso il punto, purché il punto non si trovi<br />
all'inizio del nome<br />
$ rmdir pro? Cancella tutte le directory vuote con nome pro seguito da un solo carattere qualsiasi<br />
[...] le parentesi quadre permettono di rappresentare un carattere qualsiasi o un intervallo di caratteri possibili.<br />
[adfz] Uno qualsiasi dei caratteri a,d,f,z<br />
[g-z] Uno qualsiasi dei caratteri compresi tra g e z<br />
[^a] Un carattere qualsiasi diverso da a<br />
2. Espansione della <strong>shell</strong><br />
{...} le parentesi graffe consentono di specificare un qualsiasi insieme di stringhe nella forma:<br />
prefisso{stringa1,stringa2,stringa3}suffisso<br />
Esempi:<br />
$ echo v{en,id,ic}i<br />
veni vidi vici<br />
$ echo v{en,i{d,c}}i<br />
veni vidi vici<br />
~ Utilizzato per riferirsi alle home directory dell'utente loggato<br />
~name Identifica la home dir dell'utente name<br />
$ mkdir ~/Mail (Crea una directory Mail sotto la home directory dell'utente loggato)<br />
$nomevar Espansione dei parametri d'ambiente e delle variabili (vedi sezione Variabili)<br />
$ echo $USER<br />
$(comando) Sostituisce l'output del comando<br />
$ echo Oggi e\' $(date)<br />
Oggi e' gio 24 mar 2011, 08.32.06, CET<br />
3. Regole di quoting<br />
L'inserimento di una stringa tra apici singoli ' ' protegge i caratteri speciali contenuti nella stringa dall'espansione<br />
da parte della <strong>shell</strong>.<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 16
$ echo '$HOME'=$HOME<br />
$HOME=/home/silvia<br />
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
L'utilizzo di apici doppi “ ” consente l'espansione da parte della <strong>shell</strong> dei soli nomi di variabile, mentre preserva<br />
gli altri caratteri speciali dall'espansione.<br />
$ echo "ls $HOME/* mostra il contenuto della homedir"<br />
ls /home/silvia/* mostra il contenuto della homedir<br />
Esercizi<br />
1. Listare tutti i file della cartella /var/log che contengono il carattere '-' nel nome e che terminano per '.log'.<br />
2. Listare tutti i file della cartella /var/log composti da tre caratteri e che terminano con '.log'.<br />
3. Listare tutti i file della cartella /var/log che iniziano con un carattere compreso tra 'h' e 'z' e terminano con<br />
'.log'.<br />
4. Visualizzare i file nella directory /var/log che contengono un numero all'interno del nome e terminano in '.log'.<br />
5. Il man del comando mv riporta tra le options:<br />
-t DEST_DIR Sposta tutti gli argomenti della cartella sorgente nella cartella DEST_DIR<br />
Scrivere un comando per spostare il contenuto della cartella ./folder2 all'interno della cartella ./prova1.<br />
Disegnare l'albero delle directory risultante al termine dell'operazione, supponendo che la cartella ./folder2<br />
contenga i file file1, file2, folder1. Quale comando utilizzare per spostare l'intera cartella folder2 all'interno di<br />
prova1?<br />
Espressioni Regolari<br />
Un'espressione regolare è un pattern che rappresenta un insieme di stringhe. In altre parole, è una stringa scritta<br />
secondo una precisa sintassi.<br />
Le espressioni regolari vengono tipicamente utilizzate nella ricerca di stringhe all'interno di file di testo e nella<br />
sostituzione delle stringhe trovate con nuovo testo.<br />
Usando espressioni regolari nell'effettuare ricerche, non si è obbligati a specificare esattamente i termini da<br />
ricercare, ma si possono definire delle regole generali da utilizzare per trovare le stringhe di interesse.<br />
Sintassi delle espressioni regolari<br />
1. Il caso più elementare di espressione regolare è un singolo carattere, che rappresenta l'insieme delle stringhe<br />
costituite dal solo carattere.<br />
Il carattere a, ad esempio, rappresenta l'insieme di stringhe costituito dal solo carattere {a}.<br />
2. Insiemi di caratteri<br />
Per identificare diversi caratteri è possibile utilizzare le parentesi quadre [...], come accade per il file globbing.<br />
Una lista di caratteri racchiusa tra parentesi quadre corrisponde a qualsiasi carattere in esse contenuto.<br />
Se la lista viene preceduta dal simbolo ^, l'espressione corrisponde a qualsiasi carattere non contenuto nella lista.<br />
Esempio: [^abcd]<br />
fughe mostrata perché contiene f,u,g,h,e<br />
coda mostrata perché contiene o<br />
bada non mostrata perché non contiene caratteri diversi da a,b,c,d<br />
Il carattere ^, se specificato dopo il primo carattere, assume significato letterale.<br />
L’espressione '[a^b]' mostra le linee del file che contengono i caratteri a,^ e b e non caratteri a seguiti da caratteri<br />
diversi da b.<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 17
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
All'interno delle parentesi quadre è possibile indicare un intervallo di caratteri specificando gli estremi e<br />
separandoli con il carattere -.<br />
L'espressione [a-g] mostra tutte le righe del file che contengono una lettera compresa tra a e g.<br />
Alcune localizzazioni prevedono l'ordinamento aAbBcCdD... per cui specificando [a-g] si individuano le lettere<br />
[aAbBcCdDeEfF].<br />
Si possono anche identificare classi di caratteri attraverso le espressioni:<br />
[:alnum:] Caratteri alfanumerici (cifra o lettera)<br />
[:alpha:] Caratteri alfabetici<br />
[:digit:] Caratteri numerici<br />
[:lower:] Lettere minuscole<br />
[:upper:] Lettere maiuscole<br />
[:xdigit:] Cifre esadecimali<br />
...<br />
Esempio: [[:lower:]] Seleziona tutte le righe che contengono una minuscola.<br />
3. Concatenazione<br />
Due espressioni regolari, regex1 e regex2, possono essere concatenate in una nuova espressione regolare<br />
regex1regex2. Ad essa corrisponde qualsiasi stringa formata da due stringhe concatenate corrispondenti alle<br />
singole espressioni di partenza.<br />
La più semplice forma di concatenazione è una stringa di lettere o numeri.<br />
L'espressione regolare 'ab' ricerca tutte le righe che contengono la stringa ab.<br />
L'espressione regolare 'a[1-5]' restituisce tutte le righe contenenti una delle seguenti stringhe: {a1,a2,a3,a4,a5}.<br />
4. Alternanza<br />
Due espressioni regolari, regex1 e regex2, possono essere concatenate utilizzando l'operatore pipe |.<br />
L'espressione regolare risultante corrisponde a qualsiasi stringa che corrisponda alla prima o alla seconda.<br />
L'insieme delle stringhe rappresentate dall'espressione regex1|regex2 è l'unione degli insiemi delle stringhe<br />
rappresentate da regex1 e regex2.<br />
L'espressione regolare 'a|b' visualizza le righe che contengono le stringhe che contengono la lettera a e quelle che<br />
contengono la lettera b.<br />
5. Posizionamento<br />
a. I caratteri ^ e $ identificano all'interno di un'espressione regolare rispettivamente inizio e fine riga.<br />
L'espressione regolare 'stringa$' stampa tutte le righe che terminano con stringa.<br />
L'espressione regolare '^stringa' stampa tutte le righe che iniziano con stringa.<br />
L'espressione regolare '^stringa$' stampa le righe costituite solo dalla parola stringa.<br />
b. I simboli \< e \> individuano rispettivamente l'inizio e la fine di una stringa.<br />
L'espressione regolare '\
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
Caratteri speciali della <strong>shell</strong> ed espressioni regolari<br />
Le espressioni regolari possono generare confusione perché utilizzano gli stessi caratteri speciali della <strong>shell</strong>, ma<br />
con significati a volte diversi.<br />
L'espansione dei caratteri speciali della <strong>shell</strong> viene sempre effettuata prima di eseguire un comando. Per<br />
preservare le espressioni regolari utilizzate da alcuni comandi (come ad esempio grep) da interpretazioni errate, è<br />
opportuno proteggerle con gli apici '…', evitando così che la <strong>shell</strong> interpreti i caratteri speciali di <strong>shell</strong> contenuti<br />
nell'espressione regolare. Questo è necessario anche quando i caratteri speciali hanno la stessa funzione.<br />
Caratteri speciali per le espressioni regolari<br />
Il carattere punto . è un carattere speciale che rappresenta qualsiasi carattere (lettera, cifra, spazio, tab, ...).<br />
N.B. La sintassi delle espressioni regolari differisce da quella del file globbing dove un singolo carattere è<br />
rappresentato dal carattere ?.<br />
I caratteri speciali all'interno di un'espressione regolare con le quadre [...] perdono di significato e vengono<br />
considerati letteralmente.<br />
L'espressione regolare '[\.*]' mostra le linee del file che contengono i caratteri .,\ e * e non zero o più occorrenze<br />
del carattere . (vedi sezione Operatori di ripetizione).<br />
Operatori di ripetizione<br />
Un'espressione regolare che genera una corrispondenza con un singolo carattere può essere seguita da uno o più<br />
operatori di ripetizione.<br />
Il carattere * viene specificato per cercare un'espressione ripetuta un numero qualsiasi di volte (anche zero).<br />
N.B. Notare la differenza con il carattere * del file globbing!<br />
L'espressione regolare 'ab*c' visualizza le righe che contengono le stringe {ac,abc,abbc,abbbc,ab...bc}.<br />
Il carattere ? viene specificato per cercare un'espressione ripetuta al più una volta (anche zero)<br />
L'espressione regolare 'ab?c' visualizza le righe che contengono le stringe {ac,abc}, ma non corrisponde alle<br />
stringhe {abbc,abbbc,ab...bc}.<br />
Il carattere + viene specificato per cercare un'espressione ripetuta almeno una volta.<br />
L'espressione regolare 'ab+c' visualizza le righe che contengono le stringhe {abc,abbc,abbbc,ab...bc}, ma non<br />
corrisponde alla stringa {ac}.<br />
L'espressione {n} viene specificata per cercare un'espressione ripetuta esattamente n volte.<br />
L'espressione 'ab{2}c' visualizza le righe che contengono le stringhe {abbc}, ma non corrisponde alle stringhe<br />
{ac,abc,abbbc,ab...bc}.<br />
L'espressione {n,m} viene specificata per cercare un'espressione ripetuta almeno n volte e al più m volte.<br />
L'espressione regolare 'ab{2,5}c' visualizza le righe che contengono le stringhe {abbc,abbbc,abbbbc,abbbbbc},<br />
ma non corrisponde alle stringhe {ac,abc,abbb...bbc}.<br />
L'espressione {n,} viene specificata per cercare un'espressione ripetuta almeno n volte.<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 19
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
L'espressione regolare '\' visualizza le righe contenenti stringhe che cominciano con numeri<br />
aventi almeno quattro cifre.<br />
Regole di precedenza degli operatori<br />
Nell'interpretazione delle espressioni regolari le operazioni sulle espressioni vengono valutate nel seguente<br />
ordine<br />
1) ripetizione<br />
2) concatenazione<br />
3) alternanza<br />
Le parentesi tonde possono essere utilizzate per modificare quest'ordine predefinito.<br />
L'espressione regolare 'a|bc+', esplicitando l'ordinamento delle operazioni, equivale a: '(a|(b(c+)))' overo ricerca<br />
stringhe del tipo {a, bc, bcc, bccc...}.<br />
Con le parentesi tonde possiamo modificare l'ordinamento delle operazioni:<br />
con 'a|(bc)+' ricerchiamo stringhe del tipo {a, bc, bcbc...};<br />
con '(a|b)c+' ricerchiamo stringhe del tipo {ac..., bc...}.<br />
<strong>Comandi</strong> di ricerca di stringhe<br />
grep<br />
Il comando grep (Global Regular Expression Print) viene utilizzato per cercare stringhe all'interno di un file.<br />
SINTASSI: $ grep [opzioni] 'pattern' [file]<br />
pattern è un'espressione regolare. Se il file non è specificato, grep opera sullo standard input.<br />
Opzioni:<br />
-v Stampa le righe che non contengono stringhe corrispondenti al pattern<br />
-n Antepone il numero di riga<br />
-c Visualizza soltanto quante righe contengono stringhe corrispondenti al pattern<br />
-i Rende il comando case-insensitive<br />
--color Evidenzia, colorandola, l'occorrenza del pattern all'interno della riga<br />
-E Abilita l'interpretazione di espressioni regolari estese<br />
I caratteri ?, +, {, }, |, (, e ), se utilizzati con grep che interpreta espressioni regolari base (in assenza dell'opzione<br />
-E), vanno preceduti dal carattere di escape \. Se si utilizzano con egrep o con l'opzione -E di grep, che abilita<br />
l'interpretazione di espressioni regolari estese, non è necessario anteporre il carattere \. La differenza è solo nella<br />
sintassi dell'espressione regolare non nella sua funzionalità: $ grep 'a\+' equivale a $ egrep 'a+'.<br />
Quando si proteggono gli argomenti del pattern di grep con gli apici singoli, si preclude l'utilizzo di variabili. In<br />
alcuni casi si possono utilizzare gli apici doppi, che non impediscono la sostituzione della variabile con il suo<br />
valore.<br />
$ grep “^$USER:” /etc/passwd (si veda la sezione Variabili)<br />
Esempi:<br />
Sia dato il seguente file di test denominato 'file':<br />
fughe<br />
coda<br />
bada<br />
MAIUSCOLE<br />
a1<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 20
a2<br />
a3<br />
a4<br />
a5<br />
a6<br />
a7a8<br />
a9<br />
stringa<br />
stringa stringato costringa<br />
ac<br />
abc<br />
abbc<br />
abbbc<br />
file.txt<br />
ciao a *<br />
exit<br />
^_^<br />
a^<br />
done<br />
matr 543672<br />
matr 543321<br />
matr 523455<br />
tel 0801234567<br />
prefix 080<br />
a<br />
b<br />
bc<br />
bcc<br />
bccc<br />
bcbcbc<br />
bacbc<br />
bac<br />
ac<br />
acc<br />
caa<br />
acac<br />
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
$ grep a file Mostra tutte le linee del file che contengono la lettera a almeno una volta in qualsiasi punto<br />
della riga<br />
$ grep . file Mostra tutte le linee del file che contengono almeno un carattere<br />
$ grep '[abcd]' file Mostra tutte le linee del file che contengono almeno una tra le lettere a,b,c,d<br />
$ grep '[^abcd]' file Mostra le linee del file che contengono lettere diverse da a,b,c,d<br />
fughe mostrata perché contiene f,u,g,h,e; coda mostrata perché contiene o; bada non mostrata perché<br />
non contiene lettere diverse da a,b,c,d; etc.<br />
Quale comando utilizzare per visualizzare tutte le righe che non contengono a, b, c e d?<br />
$ grep '[a-g]' file Mostra tutte le righe del file che contengono una lettera compresa tra a e g<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 21
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
$ grep [[:upper:]] file Stampa tutte le righe che contengono un carattere maiuscolo<br />
$ grep 'ad' file Stampa tutte le linee del file che contengono la stringa ad<br />
$ grep 'a[1-5]' file Ricerca una stringa di tipo {a1,a2,a3,a4,a5}<br />
$ grep 'stringa$' file Stampa tutte le righe che terminano con stringa<br />
$ grep '^stringa' file Stampa tutte le righe che iniziano con stringa<br />
$ grep '^stringa$' file Stampa le righe che contengono soltanto stringa<br />
$ grep '\' file Stampa tutte le righe che contengono una parola che termina con stringa<br />
(stringa, costringa, ma non stringato)<br />
$ grep '\' file Cosa restituisce?<br />
$ grep 'ab*c' file Visualizza le righe che contengono le stringhe: ac, abc, abbc, abbbc, ab...bc<br />
$ grep '[\.*]' file Mostra le linee del file che contengono i caratteri .,\ e * e non zero o più occorrenze<br />
del carattere .<br />
file.txt mostrata perché contiene .; ciao a * mostrata perché contiene *; etc.<br />
$ grep '[a^b]' file Mostra le linee del file che contengono i caratteri a, ^ e b e non caratteri a seguiti da<br />
caratteri diversi da b<br />
^_^ mostrata perché contiene ^; a^ mostrata perché contiene a e ^; etc.<br />
$ egrep 'ab?c' file Visualizza le righe che contengono le stringhe: ac, abc; ma non corrisponde alle<br />
stringhe: abbc, abbbc, ab...bc.<br />
$ egrep 'ab+c' file Visualizza le righe che contengono le stringhe: abc, abbc, abbbc, ab...bc; ma non<br />
corrisponde alla stringa ac<br />
$ egrep 'ab{2}c' file Visualizza le righe che contengono le stringhe abbc, ma non corrisponde alle stringhe<br />
ac, abc, abbbc, ab...bc<br />
$ egrep 'ab{2,3}c' file Visualizza le righe che contengono le stringhe abbc e abbbc, ma non corrisponde alle<br />
stringhe ac, abc, abbbbc, abbb...bbc<br />
$ grep -E '\' file Visualizza le righe contenenti i numeri con più di quattro cifre<br />
$ egrep 'a|b' file Visualizza le righe che contengono stringhe contenenti la lettera a o la lettera b<br />
$ egrep 'a|bc+' file Visualizza le righe che contengono stringhe del tipo: a, bc,bcc...<br />
$ egrep 'a|(bc)+' file Visualizza le righe che contengono stringhe del tipo: a, bc, bcbc....<br />
$ egrep '(a|b)c+' file Visualizza le righe che contengono le stringhe di tipo: ac..., bc...<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 22
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
Esercizi<br />
Scrivere un comando per visualizzare nel file /etc/passwd le righe:<br />
1. che non contengono cifre pari;<br />
2. che corrispondono ad utenti con prima lettera compresa tra g e l, ordinate in ordine alfabetico;<br />
3. che contengono la lettera 'c' ripetuta minimo 1 volta e massimo 2 volte di seguito.<br />
4. Scrivere un comando per visualizzare nel file /etc/services le righe contenenti la parola 'ftp'.<br />
5. Scrivere un comando che mostri a video tutti i file regolari contenuti nella cwd che risultano accessibili in<br />
lettura al resto del mondo.<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 23
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
Gestione utenti e gruppi<br />
Nei sistemi Unix gli utenti si dividono in: superuser (utente amministratore o root) e utenti regolari. L'utente root<br />
ha tutti i privilegi sul sistema e può aggiungere o rimuovere i privilegi agli altri utenti (diritti di accesso), così<br />
come creare nuovi utenti.<br />
Gruppi di utenti<br />
Ciascun utente di un sistema Unix appartiene ad uno o più gruppi. Ogni utente ha un unico gruppo di login<br />
(gruppo principale) di cui è titolare e può essere membro di più gruppi supplementari, a cui l'utente aderisce<br />
senza esserne il titolare. Su alcuni sistemi, l'appartenenza ad alcuni gruppi supplementari determina la possibilità<br />
di utilizzare alcune funzionalità del sistema (audio – utilizzare la scheda audio; video – utilizzare la webcam;<br />
dialout – utilizzare il modem e le porte seriali; dip – utilizzare connessioni ad internet via modem; etc.). Di fatto i<br />
gruppi servono per gestire con maggiore flessibilità l'accesso ai file e di conseguenza l'uso delle risorse.<br />
L'amministratore di sistema può creare un gruppo e gli account per gli utenti che amministreranno il gruppo.<br />
Il file /etc/group contiene l'elenco dei gruppi di utenti presenti nel sistema. Ad ogni gruppo è associata una riga<br />
nella quale si trova l'IDgroup e l'elenco degli utenti che ne fanno parte. Alcuni sistemi Linux, alla creazione di un<br />
nuovo utente, se non si specifica il gruppo principale, di default creano un gruppo con lo stesso nome dell'utente<br />
di cui l'utente diventa titolare. Altri sistemi hanno il gruppo "users" in cui vengono automaticamente inseriti tutti<br />
gli utenti aggiunti al sistema. Le righe di /etc/group si presentano nella seguente forma:<br />
GroupName:Password:GroupID:User1,User2,...,UserN<br />
GroupName Indica il nome del gruppo.<br />
Password Indica la password del gruppo. Solitamente non viene data una password al gruppo ma solo ai<br />
singoli utenti.<br />
GroupID Indica l'ID associato a quel gruppo.<br />
User1,...,UserN E' l'elenco degli users aventi tale gruppo come gruppo supplementare. I nomi dei singoli users<br />
devono essere sparati da una virgola.<br />
groupadd<br />
Crea un nuovo gruppo. Il nuovo gruppo verrà aggiunto ai file di sistema necessari.<br />
SINTASSI: # groupadd [opzioni] nome_gruppo<br />
Opzioni:<br />
[-o] -g #gid Specifica il valore numerico dell'identificatore del gruppo (#gid). Deve essere univoco, a<br />
meno che si usi l'opzione -o.<br />
groupdel<br />
Modifica i file di account del sistema, rimuovendo tutte le voci che si riferiscono al nome del gruppo specificato<br />
(che si suppone esistente). Non è possibile rimuovere il gruppo primario di un utente senza aver rimosso prima<br />
quest'ultimo.<br />
SINTASSI: # groupdel nome_gruppo<br />
groupmod<br />
Modifica la definizione di un gruppo sul sistema.<br />
SINTASSI: # groupmod [opzioni] groupName<br />
Opzioni:<br />
[-o] -g #gid Modifica l'id del gruppo groupName in #gid. Il flag -o consente l'uso di un #gid non univoco.<br />
-n group_name Modifica il nome del gruppo groupName nel nuovo nome group_name.<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 24
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
Ogni account utente è caratterizzato da: username (pubblico), userid (pubblico), password (privata), groupname<br />
(pubblico), groupid (pubblico).<br />
useradd<br />
Comando di basso livello per la creazione di un nuovo utente (analogo alla procedura guidata offerta dal<br />
comando adduser nomeutente).<br />
SINTASSI: # useradd [opzioni] nomeUtente<br />
Opzioni:<br />
-d home_dir Setta la home-directory dell'utente<br />
-m Crea la home-directory dell'utente<br />
-k /etc/skel Copia i file i file predefiniti nella home del nuovo utente<br />
-e #YYYY-MM-DD Imposta la data di scadenza dell'account<br />
-f giorni_inattività Indica il numero di giorni, che intercorrano fra la data di expire della password e la<br />
disabilitazione dell'account<br />
-g/--gid nome_gruppo/#gid Nome o #gid del gruppo principale assegnato al nuovo utente. Tale gruppo<br />
deve esistere!<br />
-G gruppo1[,gruppo2,...,gruppoN] Lista di gruppi supplementari assegnati all’utente. Tali gruppi devono esistere<br />
-p password_criptata Setta la password per il nuovo utente. La password inserita dev'essere la versione<br />
crittografata (hash MD5)<br />
-s defaultShell Nome della <strong>shell</strong> di login dell’utente<br />
[-o] -u #uid Valore numerico assegnato all’id utente. Dev'essere univoco a meno che non si usi<br />
l'opzione -o.<br />
-D [opzioni] Modifica le impostazioni di default di un nuovo utente<br />
# useradd -d /home/ciccio -m -k /etc/skel -g 100 -s /bin/bash ciccio<br />
passwd<br />
Comando che permette di settare o modificare la password di un utente. L'utente root può modificare le<br />
password di ogni utente, mentre gli utenti normali possono modificare solo la propria.<br />
SINTASSI: # passwd [opzioni] nomeutente<br />
Opzione:<br />
-d Disabilita la password per l'utente<br />
Il file /etc/passwd è il database degli utenti su ogni sistema Unix. Ad ogni user è dedicata una riga che definisce<br />
quali sono i suoi principali attributi. Sui sistemi Unix meno recenti in questo file viene scritta anche la password<br />
(criptata); su quelli più recenti essa viene scritta, generalmente, in /etc/shadow, che ha maggiori restrizioni in<br />
termini di sicurezza (visualizzate i diritti associati al file /etc/passwd).<br />
Le righe di /etc/passwd si presentano nella seguente forma:<br />
Username:Password:UserID:GroupID:Info:HomeDirectory:Shell<br />
Username Nome di login al sistema dell'utente<br />
Password Campo riservato alla password dell'utente. Può essere scritta direttamente in forma criptata o<br />
esserci semplicemente una x (la password c'è ma è scritta altrove, di solito in /etc/shadow). Se<br />
c'è un * significa che l'utente o non ha una password o la password non è valida (in questo caso<br />
non gli è permesso il login)<br />
UserID ID dell'user<br />
GroupID ID del gruppo di appartenenza<br />
Info Contiene informazioni sull'utente non necessarie al sistema (nome esteso, numero di telefono,<br />
mail,etc...)<br />
HomeDirectory Indica la directory della home dell'utente<br />
Shell Indica la <strong>shell</strong> di default per l'utente<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 25
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
Storicamente su Unix il file /etc/passwd conteneva l'elenco di tutti gli utenti e la loro password in forma criptata.<br />
Per la stessa natura di Unix, tutti gli utenti devono poter aver accesso in lettura a questo file, per cui esporre le<br />
password di tutti, seppur criptate, risultava rischioso per la sicurezza del sistema.<br />
Su tutti i sistemi Linux e Unix recenti, la gestione della password è stata migliorata sia in termini di sicurezza<br />
che di versatilità, affiancando al normale /etc/passwd la gestione del file /etc/shadow che introduce nuove<br />
funzionalità (vedi i diritti associati al file /etc/shadow e confronta con /etc/passwd). Questo file è leggibile solo<br />
dal root, mentre viene lasciato l'accesso in lettura a /etc/passwd per tutti gli utenti. Le password in /etc/shadow<br />
sono criptate con algoritmi più complessi e robusti. È possibile gestire il tempo di scadenza, la durata minima e<br />
massima e i tempi di notifica della password.<br />
Il file /etc/shadow è il database delle password sui sistemi Unix più evoluti. In esso sono elencate, per ogni<br />
utente, la password (criptata) e vari parametri ad essa connessi (ultima modifica, durata massima e minima,<br />
ecc...). Ad esso fanno riferimento diversi files, fra cui /etc/passwd e tutti i comandi per la gestione degli utenti<br />
(useradd, userdel, usermod).<br />
Le righe in /etc/shadow si presentano nella seguente forma:<br />
Username:password:lastchange:min:max:warn:inactive:expire<br />
Username Il nome dell'utente a cui fa riferimento la password<br />
Password Password criptata (13 caratteri). Può assumere anche altri valori quali * che sta ad indicare che<br />
l'utente è disabilitato e !! (o nessun carattere) che indica che l'utente non ha password<br />
lastchange Numero di giorni compresi fra il 1 gennaio 1970 e l'ultima modifica della password<br />
min Minimo numero di giorni dall'ultima data di modifica prima di poter nuovamente cambiare la password<br />
max Durata massima della password (sempre in giorni)<br />
warn Numero di giorni di preavviso all'utente prima di invalidare la password<br />
inactive Numero di giorni di inattività possibili per l'utente<br />
expire Data dopo la quale il login non può più essere effettuato<br />
userdel<br />
Rimuove l'account di un utente, ma non i file relativi.<br />
SINTASSI: # userdel [opzioni] nome_utente<br />
Opzioni:<br />
-r Rimuove anche i file della home_directory utente<br />
usermod<br />
Comando che permette di cambiare le impostazioni di un account creato precedentemente. L'utente che lancia il<br />
comando deve possedere i privilegi di amministratore.<br />
SINTASSI # usermod [opzioni] login-name<br />
Opzioni:<br />
-d home_dir Modifica la home_dir dell'utente<br />
-e expire_date Modifica l'expire_date<br />
-f inactive_days Modifica il numero di giorni che intercorrono fra la scadenza della password e la disabilitazione<br />
dell'account<br />
-g initial_group Modifica il gruppo primario<br />
-G groups Modifica i Gruppi secondari<br />
-l login Cambia il nome di login dell'utente<br />
-p password Modifica la password criptata (sconsigliato)<br />
-s <strong>shell</strong>s Modifica la <strong>shell</strong> di default dell'utente<br />
-u UID Modifica l'UID<br />
-L Esegue il lock dell'account<br />
-U Operazione inversa del lock, ovvero riabilita l'account<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 26
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
su (substitute user)<br />
Cambia id utente o diventa superuser, se il nome utente non è specificato.<br />
SINTASSI: $ su [opzioni] [nomeutente]<br />
Opzioni:<br />
-l Fornisce un ambiente simile a quello di login dell'utente<br />
$ su (si intende root)<br />
Esercizi<br />
1. Creare un nuovo gruppo di nome 'new' assegnando l'id 1001 che corrisponde al gid di un gruppo esistente.<br />
2. Creare un nuovo utente con lo stesso nome del gruppo appena creato e assegnargli il gruppo new.<br />
3. Cambiare il gruppo principale dell'utente appena creato in userA e assegnare l'utente al gruppo supplementare<br />
supA.<br />
4. Rimuovere il gruppo creato all'esercizio 1. Viene rimosso anche il gruppo con #gid=1001?<br />
5. Definire una serie di comandi che consentano di creare manualmente un nuovo utente, senza far ricorso ai<br />
comandi useradd o adduser. Si suppone che il comando di riferimento sia:<br />
useradd -u 1006 --gid 1007 -d /home/ciccio -m -k /etc/skel -s /bin/bash ciccio<br />
a. Loggarsi come amministratore<br />
b. Editare il file /etc/passwd<br />
ciccio:x:1006:1007::/home/ciccio:/bin/bash<br />
c. Editare il file /etc/group<br />
ciccio:x:1007<br />
d. Editare il file /etc/shadow<br />
ciccio:......:15482:0:999:7:::<br />
e. Creare la home directory<br />
mkdir /home/ciccio<br />
f. Inizializzare i file della home<br />
cp /etc/skel/* /home/ciccio<br />
g. Cambiare il proprietario della home directory<br />
chown ciccio:ciccio /home/ciccio<br />
h. Cambiare i diritti di accesso alla home directory<br />
chmod 700 /home/ciccio<br />
i. Impostare una password per l'utente ciccio<br />
passwd ciccio<br />
<strong>Comandi</strong> informativi<br />
Consentono di ottenere dal sistema informazioni sugli utenti.<br />
id<br />
Mostra gli identificatori numerici (uid, gid, groups), e i nomi simbolici ad essi associati, dell'utente indicato<br />
come argomento.<br />
SINTASSI: $ id [opzioni] [nomeutente]<br />
Opzioni:<br />
-u Filtra sull'utente (mostra solo l'id)<br />
-g Filtra sul gruppo principale (mostra solo l'id)<br />
-G Filtra sui gruppi supplementari (mostra solo l'id)<br />
-n Se utilizzato assieme a -u, -g e -G mostra solo il nome anzichè l'id numerico<br />
silvia@ubuntu:~ id silvia<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 27
whoami<br />
Mostra chi è l'utente della <strong>shell</strong><br />
SINTASSI: $ whoami<br />
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
who<br />
Mostra tutti gli utenti correntemente connessi al sistema e i relativi dati (nome del terminale, data-ora)<br />
SINTASSI: $ who [opzioni]<br />
Opzioni:<br />
-a Mostra tutti gli utenti<br />
-l Mostra il login dei processi di sistema<br />
-q Mostra il nome degli utenti loggati e il loro numero complessivo<br />
-r Mostra il runlevel corrente<br />
groups<br />
Mostra i nomi dei gruppi a cui appartiene l'utente correntemente loggato o di quello specificato.<br />
SINTASSI: $ groups [nome_utente]<br />
last<br />
Lista gli ultimi login/logout degli utenti sul sistema e gli ultimi riavvii del sistema, interpellando il file<br />
/var/log/wtmp, altrimenti non visualizzabile.<br />
Visualizza: nome utente, console di login, identificativo del display, kernel, data di login, tempo di permanenza.<br />
SINTASSI: $ last [nomeutente]<br />
$ last root<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 28
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
Variabili<br />
Permettono di memorizzare stringhe ed interi. I nomi sono case sensitive e possono contenere lettere, cifre e<br />
underscore '_', ma non spazi o punteggiatura; non possono iniziare con una cifra.<br />
Definizione<br />
SINTASSI: $ nomevar=valore<br />
$ a=5<br />
$ msg=”Benvenuti alla”<br />
Il valore di una variabile viene visualizzato attraverso il comando echo seguito dal nome della variabile<br />
preceduto dal simbolo $. Per delimitarne il nome si usano le parentesi graffe.<br />
$ echo $msg ${a}a lezione<br />
Benvenuti alla 5a lezione<br />
Variabili d'ambiente<br />
L'ambiente è un insieme di variabili che condizionano un processo eseguito dalla <strong>shell</strong>. Una variabile d'ambiente<br />
contiene valori di comodo caratteristici dell'ambiente di <strong>shell</strong> di un dato utente, è visibile a tutti i programmi<br />
eseguiti dalla <strong>shell</strong>, fornisce informazioni ai programmi ed eventualmente ne condiziona l'esecuzione.<br />
printenv<br />
Il comando printenv (print environment) stampa l'elenco delle variabili d'ambiente. Se provvisto di argomento,<br />
stampa il valore della variabile d'ambiente.<br />
SINTASSI: $ printenv [nomevariabile]<br />
USER Utente che esegue la bash<br />
HOME Home directory dell'utente che esegue la <strong>shell</strong><br />
PS1 Prompt<br />
HOSTNAME Nome del computer<br />
SHELL Pathname assoluto della <strong>shell</strong> in uso<br />
PWD Percorso della cwd<br />
OLDPWD Percorso della directory precedentemente visitata<br />
UID Identificativo numerico dell'utente loggato<br />
GROUPS Vettore degli ID dei gruppi a cui l'utente appartiene<br />
PPID Process ID del processo genitore della <strong>shell</strong> attuale<br />
PATH<br />
La variabile PATH contiene i percorsi in cui la <strong>shell</strong> ricerca gli eseguibili dei comandi, memorizzati sottoforma<br />
di elenco di directory separate da due punti. Il valore di default per tutti gli utenti è impostato<br />
dall'amministratore. L'utente può modificarla nel corso dell'esecuzione inserendo un path a cui fa spesso<br />
riferimento o fare in modo che venga modificata ad ogni avvio. Tale variabile serve ad evitare che l'utente che si<br />
interfaccia con la <strong>shell</strong> debba scrivere per ogni comando tutto il percorso.<br />
# echo $PATH<br />
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin<br />
$ echo $PATH<br />
/usr/local/bin:/usr/bin:/bin:/usr/games<br />
Nell'esecuzione di un comando distinguiamo 2 casi.<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 29
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
1) Quando il comando non contiene il carattere '/', la <strong>shell</strong> tenta di localizzarlo mediante i seguenti passi:<br />
a. verifica che il comando sia una funzione della <strong>shell</strong>;<br />
b. verifica che sia un comando incorporato (built-in);<br />
c. cerca nelle directory specificate nell'ordine in cui sono elencate nella variabile PATH un file<br />
eseguibile con il nome specificato. La <strong>shell</strong> esegue il primo file eseguibile con il nome specificato che<br />
trova.<br />
2) Quando il comando contiene uno o più '/', la <strong>shell</strong> esegue il programma corrispondente al pathname<br />
specificato. Quando si specifica il pathname per eseguire un comando, è necessario utilizzare almeno un<br />
carattere '/'.<br />
Per eseguire un comando il cui file è nella directory corrente, sarà necessario utilizzare la sintassi ./nome_file.<br />
Per ovviare a questo problema è possibile inserire la directory '.' nella variabile PATH.<br />
Exit status (?)<br />
Ogni comando <strong>shell</strong>, al termine dell'esecuzione, fornisce un exit status ovvero un valore intero compreso tra 0 e<br />
255 che ne descrive l'esito dell'esecuzione. Per convenzione:<br />
0 indica che il programma è stato eseguito con successo;<br />
[1-255] indica che il programma non è terminato correttamente (il significato del valore dell'exit status è<br />
descritto nella pagina di manuale).<br />
La <strong>shell</strong> memorizza l'exit status dell'ultimo comando eseguito nella variabile ?.<br />
$ cat /etc/shadow<br />
$ echo $?<br />
1<br />
export<br />
Per rendere d'ambiente una variabile dichiarata si usa il comando export.<br />
L'assegnazione o la creazione di una variabile ha validità solo nel'ambito della <strong>shell</strong> stessa.<br />
SINTASSI: $ export nome[=valore]<br />
set/unset<br />
Il comando set visualizza tutte le variabili definite nella <strong>shell</strong> in esecuzione, anche quelle create manualmente.<br />
Il comando:<br />
SINTASSI: $ unset nomevariabile<br />
rimuove la variabile.<br />
Esercizi<br />
1. Copia il file /bin/echo nella tua home directory ed eseguilo con gli argomenti “Hello World!”<br />
2. Aggiungi alla variabile PATH la directory '.' facendo in modo che il comando echo eseguito sia sempre quello<br />
della copia nella tua home directory.<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 30
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
Visualizzazione ed editing di file<br />
cat<br />
Il comando cat (concatenate) legge ogni file argomento in sequenza e mostra sullo standard output il contenuto,<br />
ovvero concatena file. L'operazione non genera alcun file e si utilizza per controllare il contenuto di file testuali.<br />
SINTASSI: $ cat [opzioni] file<br />
Opzione:<br />
-n Numera le righe sullo stdout<br />
Esempio:<br />
file1: Questo è il primo file<br />
file2: Questo è il secondo file<br />
$ cat file1<br />
$ cat file1 file2<br />
file<br />
Visualizza il tipo di uno o più file.<br />
SINTASSI: $ file file_esempio<br />
user@ubuntu:~$ file ./*<br />
./esempio_sort_num.txt: ASCII text<br />
./esempio_sort.txt: ASCII text<br />
./esempio_uniq.txt: UTF-8 Unicode text<br />
./file_esempio.txt: ASCII text<br />
Esercizio: Che tipo di file è il file /var/log/wtmp?<br />
less (more)<br />
Visualizza un file in modo interattivo. Apre il paginatore e formatta il testo in pagine per facilitarne la lettura.<br />
SINTASSI: $ less nomefile<br />
more è un paginatore alla stregua di less, ma consente solo lo scorrimento delle pagine in avanti.<br />
N.B. I paginatori si possono scorrere con i tasti invio, spazio e frecce. Per uscire dal paginatore si usa Q. Per<br />
chiedere l'help del paginatore si usa H.<br />
$ ls -l | less (Si veda la sezione Operatori di redirezione)<br />
Esercizi<br />
1. Visualizzate il contenuto del file /etc/passwd.<br />
2. Visualizzate l'inizio e la fine del file /etc/passwd attraverso un paginatore.<br />
3. Determinare la tipologia dei file /etc/passwd e /bin/ls.<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 31
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
Canali di comunicazione e ridirezione<br />
I programmi dispongono di 3 canali di comunicazione standard (standard file descriptor):<br />
0 Standard input (tastiera)<br />
1 Standard output (terminale)<br />
2 Standard error (terminale)<br />
La <strong>shell</strong> consente il reindirizzamento dei 3 canali standard all'interno di file con la sintassi:<br />
$ comando operatore file<br />
Operatori di ridirezione dello standard output<br />
Ridirige lo std output del comando sul file. Se il file non esiste, viene creato; se il file esiste, viene sovrascritto<br />
(>) oppure il nuovo output viene accodato (>>).<br />
SINTASSI: $ comando > file<br />
> ridirige lo standard output in modalità truncate<br />
SINTASSI: $ comando >> file<br />
>> ridirige lo standard output in modalità append<br />
$ who<br />
$ who > whofile<br />
$ cat whofile<br />
$ ls -l > stdout.txt<br />
$ cat stdout.txt<br />
$ echo parola esempio >> file_prova<br />
$ cat file1 file2 > file3<br />
Operatori di ridirezione dello standard error<br />
Ridirige lo std error del comando su file. Se il file non esiste, viene creato; se il file esiste, viene sovrascritto (2>)<br />
oppure il nuovo output viene accodato (2>>).<br />
SINTASSI: $ comando 2> file<br />
2> ridirige lo standard error in modalita truncate<br />
SINTASSI: $ comando 2>> file<br />
2>> ridirige lo standard error in modalità append<br />
Operatori di ridirezione dello standard input<br />
Ridirige lo std input del comando su file, cioè fa sì che l'input di un comando provenga, anziché da tastiera, da<br />
un file.<br />
SINTASSI: $ comando < file<br />
< ridirige lo standard input<br />
$ grep 'ciao' /home/silvia/file<br />
$ grep 'ciao' < /home/silvia/file<br />
L'interprete standard di comandi (sh), permette di eseguire comandi letti da una stringa a riga di comando (-c),<br />
dallo standard input (-s) o da un file specificato.<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 32
comandi<br />
pwd<br />
ls<br />
echo “comandi“<br />
mkdir redirectdir<br />
$ sh < comandi<br />
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
SINTASSI: $ comando (&>>)<br />
SINTASSI: $ comando &> filename<br />
Più reindirizzamenti possono essere effettuati nella stessa linea di comando:<br />
$ comando < in > out 2> err<br />
Operatore di pipeline<br />
Canale di ridirezione che collega lo standard output di un programma allo standard input di un altro (vedi figura).<br />
Utilizza il simbolo |.<br />
SINTASSI: $ comando1 | comando2 | …<br />
$ ls -l /etc | less<br />
Liste di comandi<br />
Sulla stessa linea di comando è possibile eseguire una lista di comandi separandoli con caratteri speciali.<br />
Tipi di esecuzione:<br />
sequenza<br />
SINTASSI: $ comando1 ; comando2<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 33
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
Indipendentemente dal loro exit status, con ';' i due comandi vengono eseguiti in sequenza (prima comando1 e<br />
poi comando2) .<br />
$ env > env-silvia ; cp env-silvia /tmp/<br />
$ ls -l /tmp/env-* env-* (Per verifica)<br />
$ (date;ls) > compfile<br />
concorrenza<br />
SINTASSI: $ comando1 & comando2<br />
Il comando1 viene eseguito in background, il comando2 in foreground (si veda la sezione Gestione dei processi).<br />
condizione<br />
SINTASSI: $ comando1 && comando2<br />
Il comando1 viene eseguito sempre; il comando2 soltanto se il primo è terminato con successo (exit status 0).<br />
Supponiamo che il file /tmp/env1 non esista<br />
$ cp /tmp/env-silvia1 . && cat env-silvia1 env-silvia > env-silviax2<br />
In questo caso cat non viene eseguito perche' cp non ha trovato il file da copiare. Una volta generato il file da<br />
copiare, eseguendo lo stesso comando il cat verrà eseguito perché cp terminerà senza errori.<br />
esclusione<br />
SINTASSI: $ comando1 || comando2<br />
Il comando1 viene sempre eseguito; il comando2 soltanto se il primo è terminato con exit status diverso da 0.<br />
$ chown silvia /tmp/env-vito || rm -f env-silvia<br />
In questo caso il secondo rm viene eseguito perché l'utente corrente non può cambiare il proprietario di un file.<br />
$ rm -f /tmp/env-silvia || rm -f env-silvia1<br />
In questo caso il secondo rm non viene eseguito perché il primo rm termina senza errori.<br />
Exit status di liste di comandi<br />
Quando si eseguono più programmi in una sola linea di comando (come nelle pipeline o nelle liste di comandi),<br />
l'exit status è relativo all'ultimo comando eseguito.<br />
Script BASH<br />
Non c'è differenza tra quello che si può scrivere utilizzando la <strong>shell</strong> interattivamente o mediante uno script.<br />
Uno script di <strong>shell</strong> BASH è un file di testo che:<br />
- contiene comandi di <strong>shell</strong>;<br />
- inizia con la stringa “#!/bin/bash”;<br />
- ha permesso di esecuzione.<br />
I primi due caratteri #! indicano che il file è uno script o più in generale un programma interpretato. La stringa<br />
successiva è il pathname dell'interprete per il programma.<br />
La <strong>shell</strong> esegue l'interprete specificato nella prima linea passandogli come argomento il nome dello script.<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 34
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
Filtri e programmi di utilità generica<br />
I programmi introdotti qui di seguito, così come cat, less e quasi tutti i comandi Unix, in mancanza di specifiche<br />
diverse fornite a linea di comando effettuano una trasformazione sullo standard input.<br />
sort ordina le linee di un file di testo<br />
wc è un programma che permette di contare caratteri, parole e linee<br />
head e tail estraggono linee da un file di testo<br />
uniq elimina linee ripetute consecutive da un file<br />
cut estrae sezioni di una riga di testo<br />
diff confronta due file di testo<br />
grep seleziona linee di specificata struttura (vedi sezione <strong>Comandi</strong> di ricerca di stringhe)<br />
sort<br />
Ordina il file ottenuto concatenando i file indicati, e scrive il risultato sullo standard output. Se non è indicato<br />
alcun file, ordina lo standard input.<br />
SINTASSI: $ sort [opzioni] [file1 ... fileN]<br />
Opzioni:<br />
-b Ignora i blank iniziali (spazi e tabulazioni)<br />
-c Controlla se i file indicati sono già ordinati. Se non lo sono, viene emessa una segnalazione di errore<br />
e il programma mostra la prima riga che non rispetta l'ordine.<br />
-d Dictionary order: ignora tutti i caratteri che non siano lettere, numeri o spazi<br />
-f Non distingue tra lettere maiuscole e minuscole<br />
-i Ignora i caratteri speciali al di fuori del set ASCII puro (ignora caratteri non stampabili)<br />
-m Fonde insieme i file indicati che devono essere già ordinati (non effettua ordinamento)<br />
-n Sort numerico: considera anche il segno meno e il punto decimale<br />
-r Reverse: inverte il senso di ordinamento<br />
-o file Utilizza il file indicato per inserire il risultato dell'operazione, invece di utilizzare lo standard output<br />
$ cat numeri<br />
10<br />
1<br />
2<br />
5<br />
77<br />
750<br />
8<br />
$ sort numeri<br />
$ sort -r numeri<br />
$ sort -n numeri<br />
$ cat esempio_sort.txt<br />
RIGA A<br />
RIGA B<br />
RIGA D<br />
RIGA C<br />
$ sort esempio_sort.txt<br />
$ sort -c esempio_sort.txt<br />
$ sort numeri esempio_sort.txt > sort1<br />
$ sort -o sort numeri esempio_sort.txt<br />
$ cat esempio_sort_num.txt<br />
1.1<br />
100<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 35
5<br />
11<br />
$ sort esempio_sort_num.txt<br />
$ sort -n esempio_sort_num.txt<br />
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
wc<br />
Conta e mostra il numero di linee (-l), il numero di parole (-w), il numero di caratteri (-m) e il numero di byte<br />
(-c) di uno o più file. L'opzione di default è -lwc (righe, parole e byte).<br />
SINTASSI: $ wc [-lwmc] [file]<br />
Formato risposta: [righe] [parole] [caratteri] [byte] nome_file<br />
I campi restituiti dalla risposta vengono mostrati sempre nell'ordine del formato della risposta,<br />
indipendentemente dall'ordine di inserimento dei flag nel comando. Semplicemente viene effettuato un filtro dei<br />
campi mostrati a seconda che vengano o meno inseriti tutti i flag.<br />
$ cat elencotel<br />
roberto 48000529<br />
marco 3452328<br />
mario 5567843<br />
luigi 67421467<br />
$ wc elencotel<br />
4(n.linee) 8(n. parole) 60(n. byte) elencotel<br />
$ wc -w -l -m -c esempio_uniq.txt<br />
6 37 209 215 esempio_uniq.txt<br />
head<br />
Copia le prime X linee o byte di un file sullo standard output (default X=10). Se nessun file è specificato, copia<br />
linee dallo standard input.<br />
SINTASSI: $ head [opzioni] [filename]<br />
Opzioni:<br />
-c #X Mostra i primi #X byte di un file<br />
-c -#X Mostra i byte di un file esclusi gli ultimi #X byte<br />
-n #X Mostra le prime #X righe di un file (equivale a -#X)<br />
-n -#X Mostra le righe di un file escluse le ultime #X<br />
$ cat elencotel<br />
$ head -1 elencotel (equivale a $ head -n 1 elencotel)<br />
$ head -n -1 elencotel<br />
$ head -c 6 file_esempio.txt<br />
15 fif<br />
tail<br />
Copia il file sullo standard output, iniziando da un posto specificato (linee, blocchi o caratteri dall'inizio o dalla<br />
fine del file). Se non è specificato nessun file, copia lo standard input. Mostra le ultime righe o byte di un file, di<br />
default le prime 10 righe.<br />
SINTASSI: $ tail [opzioni] [file]<br />
Opzioni:<br />
-c #X Mostra gli ultimi #X byte di un file<br />
-c +#X Mostra gli ultimi byte di un file a partire dal byte #X<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 36
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
-n #X Mostra le ultime #X righe di un file (equivale a -#X)<br />
-n +#X Mostra le ultime righe di un file a partire dalla riga #X<br />
$ cat elencotel<br />
$ tail -c +3 elencotel<br />
$ tail -n 3 elencotel<br />
$ tail -c 3 file_esempio.txt<br />
ne (l'ultimo byte è EOF!)<br />
$ tail -n +13 file_esempio.txt<br />
3 three<br />
2 two<br />
1 one<br />
and mission...<br />
uniq<br />
Mostra od omette le linee ripetute. Se non è specificato nessun flag, visualizza tutte le righe senza ripetizioni.<br />
SINTASSI: $ uniq [opzioni] file<br />
Opzioni:<br />
-c Per ogni riga indica il numero di occorrenze<br />
-d Mostra solo le linee duplicate<br />
-f N Salta il confronto delle prime N parole<br />
-i Nel confronto ignora la differenza tra lettere maiuscole e minuscole<br />
-s N Salta il confronto dei primi N caratteri<br />
-u Mostra solo le linee uniche non duplicate<br />
-w N Confronta non più di N caratteri per riga<br />
$ cat esempio_uniq.txt<br />
Questa riga è presente una sola volta.<br />
Questa riga è presente due volte.<br />
Questa riga è presente due volte.<br />
Questa riga è presente tre volte.<br />
Questa riga è presente tre volte.<br />
Questa riga è presente tre volte.<br />
$ uniq esempio_uniq.txt<br />
$ uniq -cd esempio_uniq.txt<br />
$ uniq -u esempio_uniq.txt<br />
$ uniq -cs 22 esempio_uniq.txt<br />
cut<br />
Permette di estrarre sezioni di una riga di testo, delimitate da un carattere separatore.<br />
SINTASSI: $ cut [opzioni] [file]<br />
Opzioni:<br />
-b range Estrae solo i byte indicati nel range (N, N-M, -N, N-)<br />
-c range Estrae solo i caratteri indicati nel range (N, N-M, -N, N-)<br />
-d separatore Indica il carattere/stringa separatore da utilizzare (anzichè TAB)<br />
-f intervallo Indica la lista dei campi da estrarre (N, N-M, -N, N-)<br />
$ cat cut_file<br />
nome cognome matricola<br />
pippo pluto 123456<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 37
ciccio pallino 098765<br />
$ cut -f 2 cut_file<br />
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
$ cat cut_file_delim<br />
nome;cognome;matricola;email;CDL<br />
pippo;pluto;123456;p.p@p.it;AUT<br />
ciccio;pallino;098765;ciccio@gmail.com;INF<br />
$ cut -d \; -f 2-3,5 cut_file_delim<br />
Considera ogni riga composta da più stringhe separate dal (;) e ne visualizza solo la seconda, la terza e la quinta.<br />
diff<br />
Trova differenze tra due file. Questo comando risulta molto utile per confrontare i file di configurazione. Se si<br />
sostituisce a uno dei file da confrontare il trattino (-), questo indica che il confronto verrà eseguito con lo<br />
standard input.<br />
SINTASSI: $ diff [opzioni] file1 file2<br />
Opzioni:<br />
-b Ignora le differenze nella quantità di spazi bianchi<br />
-B Ignora le differenze che consistono solo in righe vuote<br />
-r Confrontando due directory, confronta ogni sottodirectory ricorsivamente<br />
--brief Riferisce solo se i file sono diversi, senza mostrarne le differenze<br />
--ignore-case Considera allo stesso modo maiuscole e minuscole, ignorando ogni relativa differenza<br />
$ diff –brief /etc/passwd /etc/shadow<br />
colordiff<br />
Il comando ha le stesse opzioni ed effetti di diff ma mostra un output colorato che permette una maggiore<br />
leggibilità.<br />
Esercizi<br />
1. Conta il numero di linee contenute nel file /etc/passwd<br />
2. Visualizza le righe del file /etc/passwd in ordine alfabetico<br />
3. Nella pagina di manuale di sort trova l'opzione per l'ordinamento numerico<br />
4. Conta i file che terminano con '.log' nella directory /var/log<br />
5. Sapendo che l'opzione '-k POS' del comando sort consente di ordinare le righe di un testo in base al k-esimo<br />
campo, ordina i file nella tua directory in base al numero di link e visualizza l'elenco con less.<br />
6. Visualizza i file in /etc e le relative informazioni ordinati per dimensione.<br />
7. Crea un file contenente tutte le variabili di ambiente denominato env-MATR e copialo sotto /tmp. Concatena i<br />
due file e visualizza il contenuto ordinato senza mostrare le linee ripetute. Visualizza prima le linee che non<br />
presentano, ripetizioni poi quelle ripetute.<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 38
Avvio del sistema<br />
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
Gestione dei processi<br />
Il BIOS (Basic Input Output System) è l'insieme di routine eseguite all’avvio del sistema e che svolgono funzioni<br />
di collegamento tra il software e l’hardware (controllano la presenza di RAM, le periferiche IDE, la tastiera,<br />
etc.). Il BIOS si occupa di caricare il primo settore (Master Boot Record) del primo cilindro del dispositivo di<br />
boot (di default il primo hard disk del primo canale IDE) ed esegue le istruzioni in esso contenute, cedendo il<br />
controllo del sistema al Boot Loader, un piccolo programma contenuto nei primi 512 byte del Master Boot<br />
Record che si occupa di caricare il kernel in memoria ed eseguirlo.<br />
Un singolo boot loader è in grado di caricare molti tipi di kernel e quindi anche diversi sistemi operativi presenti<br />
in partizioni differenti. Naturalmente può essere caricato un solo kernel per volta.<br />
Il kernel di GNU/Linux, cioè Linux, è in grado di accettare parametri da riga di comando. Una volta avviato, si<br />
decomprime, esamina ed elabora i parametri passati ed avvia /sbin/init. Il processo init è il primo processo<br />
eseguito subito dopo la fase di bootstrap del sistema, dopo che il kernel è stato caricato, ed è avviato direttamente<br />
dal kernel.<br />
init viene spesso denominato il genitore di tutti i processi presenti su un sistema GNU/Linux (più correttamente è<br />
l'avo di tutti i processi), rimane attivo per tutto il funzionamento del sistema ed ha il compito di inizializzare e<br />
gestire il sistema ad un livello più alto di quello del kernel, per permetterne l'utilizzo da parte degli utenti.<br />
Il suo ruolo fondamentale è quello di eseguire tutti i processi necessari al funzionamento del sistema secondo le<br />
direttive specificate nel file /etc/inittab, in cui ogni riga ha una struttura di tipo id:runlevel:action:process:<br />
id: identificatore univoco della riga;<br />
runlevel: elenco dei runlevel per i quali il comando specificato deve essere applicato;<br />
action: azione da intraprendere da parte di init;<br />
command: nome del file eseguibile associato all'azione.<br />
init svolge una serie di compiti amministrativi fondamentali per il funzionamento del sistema e non può mai<br />
essere terminato. La riga contenente la direttiva sysinit è indipendente dal runlevel corrente ed è associata ad un<br />
file eseguibile che si occupa di eseguire le operazioni preliminari, di configurazione del sistema.<br />
Successivamente vengono avviati i servizi per l’utilizzo del sistema, i deamon.<br />
/etc/inittab contiene solitamente istruzioni per l'attivazione dei terminali e la specifica del runlevel di default.<br />
Runlevel<br />
Linux può funzionare in modalità diverse, ovvero la sua esecuzione dipende dal valore di un parametro<br />
importantissimo detto runlevel, per mezzo del quale init cambia la modalità di funzionamento del sistema. Un<br />
runlevel è una configurazione software che specifica i servizi da attivare o disattivare sul sistema.<br />
I valori di runlevel riservati sono:<br />
0: halt, spegnimento del sistema<br />
1: single user mode<br />
6: reboot, riavvio del sistema<br />
Quelli configurabili vanno dal 2 al 5 e ciascuna versione di UNIX o distribuzione di Linux attribuisce loro un<br />
significato (3: full multi user; 5: full multi user + sessione grafica).<br />
Il comando<br />
SINTASSI: $ runlevel<br />
restituisce il valore del runlevel corrente.<br />
Digitando il comando<br />
SINTASSI: $ init numero_ runlevel<br />
si manda il sistema in esecuzione in quel runlevel.<br />
# init 6<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 39
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
La direttiva initdefault in /etc/inittab indica il runlevel di default di avvio del sistema: id:2:initdefault: .<br />
I servizi da attivare o disattivare in ciascun runlevel sono specificati nelle directory /etc/rcX.d dove X è il<br />
runlevel.<br />
shutdown<br />
Spegne il sistema in maniera sicura. Tutti gli utenti loggati ricevono un messaggio quando viene eseguito tale<br />
comando. È possibile spegnere o riavviare il sistema immediatamente, dopo un intervallo di tempo, oppure ad un<br />
orario prefissato mediante l’argomento time, che può avere diversi formati: now (spegne il sistema<br />
immediatamente); +m (spegne il sistema dopo m minuti); hh:mm (specifica l'orario di spegnimento).<br />
SINTASSI: $ shutdown [-krh] time [messaggio_avviso]<br />
Opzioni:<br />
-k Non spegne realmente il sistema, ma manda il messagio di avviso specificato a tutti gli utenti connessi<br />
-r Riavvia il sistema dopo lo spegnimento, equivalente a $ init 6<br />
-h Spegne il sistema, equivalente a $ init 0<br />
Controllo dei processi<br />
L'istanza di un programma in esecuzione in ambiente UNIX viene detta processo. Ogni programma può generare<br />
diversi processi. Ad esempio, ogni utente collegato al sistema esegue la sua <strong>shell</strong>; ogni utente può eseguire<br />
un'istanza di vi.<br />
Nei sistemi Unix ad ogni processo è assegnato un intero univoco, compreso tra 0 e 32767, denominato PID<br />
(process identification number), e un parent PID (PPID), ovvero il PID del processo che lo ha generato.<br />
Il sistema operativo assegna ad ogni nuovo processo un PID che il processo mantiene fino alla sua terminazione.<br />
I PID possono essere riutilizzati dopo la conclusione del processo e associati ad un nuovo processo. La maggior<br />
parte delle implementazioni di UNIX utilizza un algoritmo che posticipa il più possibile il riuso dei PID in modo<br />
da evitare che processi eseguiti a breve distanza di tempo utilizzino lo stesso PID.<br />
Il processo con PID 0 è solitamente lo scheduler (anche noto come swapper). Al processo init, invece, è<br />
associato PID=1 e nessun PPID.<br />
Tutti gli altri processi si creano tramite system call fork a partire da init. Il nuovo processo è detto processo<br />
“figlio” mentre il processo che ha invocato la fork è detto processo “genitore”. Nell'esecuzione dei programmi, il<br />
sistema operativo UNIX effettua normalmente le seguenti operazioni:<br />
1. creazione di un nuovo processo;<br />
2. esecuzione del programma figlio nello spazio del nuovo processo;<br />
3. attesa dal processo padre della terminazione del processo figlio;<br />
4. terminazione dell'esecuzione del processo figlio.<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 40
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
fork è una system call speciale che viene invocata una volta, ma in caso di successo ritorna due volte e restituisce<br />
due valori diversi: una volta nel genitore restituendo il PID del figlio; una volta nel figlio restituendo 0.<br />
La fork restituisce il PID del figlio per consentire al genitore di tenere traccia del processo generato. Ogni<br />
processo può avere più figli e non esistono system call che elenchino i figli di un dato processo, mentre ogni<br />
processo ha sempre un unico genitore.<br />
Il processo figlio è una copia integrale del genitore. Il figlio ha una copia delle variabili del processo genitore,<br />
quindi la modifica di una variabile nello spazio di indirizzamento del figlio non modifica la variabile nel<br />
processo genitore.<br />
Dopo la fork, in entrambi i processi viene eseguita l'istruzione successiva alla fork. Il modo più semplice per<br />
distinguerli ed eseguire istruzioni diverse nel genitore e nel figlio è controllare il valore di ritorno della fork.<br />
La fork consente anche di suddividere il carico di lavoro tra diversi processi assegnando ad ognuno di essi parte<br />
del lavoro. Un caso frequente è quello di un programma che fornisce un determinato servizio: ad ogni richiesta<br />
ricevuta, il processo genera un figlio e gli assegna la richiesta da servire, mentre il genitore ritorna in attesa di<br />
nuove richieste.<br />
Ad ogni processo sono associati due utenti:<br />
Real user: utente che ha lanciato il processo;<br />
Effective user: utente che determina i diritti del processo.<br />
Solitamente i due utenti coincidono, ma quando un file eseguibile ha il set-uid-bit impostato, il corrispondente<br />
processo avrà:<br />
Real user: utente che ha lanciato il processo<br />
Effective user: utente proprietario dell'eseguibile.<br />
Questo metodo consente agli utenti di effettuare operazioni che normalmente non potrebbero fare e al<br />
programma di stabilire l'effettiva identità dell'esecutore. Il processo figlio eredita dal genitore una serie di<br />
proprietà tra cui real ed effective UID.<br />
Esempio : Il comando passwd<br />
Il comando passwd serve per modificare la password d'accesso al sistema. Quando eseguito da un utente<br />
normale, chiede all'utente la vecchia password, poi una volta verificato che la password coincide, chiede una<br />
nuova password 2 volte e sostituisce il campo corrispondente nel file di password del sistema (normalmente<br />
/etc/shadow). L'utente che esegue passwd non ha il permesso di modificare il file di sistema, ma il programma<br />
passwd ha il set-uid-bit impostato.<br />
$ ls -la /usr/bin/passwd<br />
-rwsr-xr-x 1 root root 42824 apr 9 2012 /usr/bin/passwd<br />
Quando viene eseguito da root, il comando passwd permette di cambiare la password di qualsiasi utente. Non<br />
chiede mai la vecchia password (neanche quando si tratta della password di root). Dal momento che qualsiasi<br />
utente esegua passwd ottiene i permessi di root, il comando passwd per accorgersi di essere stato eseguito da root<br />
confronta Real ed Effective user.<br />
ps<br />
Il comando ps (process status) visualizza i processi in esecuzione sul sistema (è una snapshot statica).<br />
Di default su ogni processo dell'elenco vengono visualizzate le seguenti informazioni: il PID, il terminale (TTY)<br />
da cui il processo è stato lanciato, il tempo di CPU utilizzato dal processo (TIME) ed il comando (CMD). In<br />
assenza di opzioni, visualizza i processi eseguiti dalla <strong>shell</strong> corrente in ordine crescente di PID.<br />
SINTASSI: $ ps [opzioni]<br />
PID TTY TIME CMD<br />
2532 pts/1 00:00:00 bash<br />
2590 pts/1 00:01:06 yes<br />
2658 pts/1 00:00:00 ps<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 41
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
Opzioni:<br />
a (all) Mostra i processi di tutti gli utenti<br />
-e Visualizza tutti i processi<br />
-f (full) Visualizza anche UID (effective user), PPID, argomenti e start time (STIME)<br />
-F (father) Visualizza informazioni ancora più dettagliate rispetto a -f<br />
f Visualizza lo stato (STAT) e la dipendenza padre/figlio (COMMAND)<br />
-o Consente di specificare l'elenco di informazioni da visualizzare<br />
-p [lista_PID] Solo le informazioni relative ai PID specificati<br />
-r (running) Restringe la selezione solo ai processi in esecuzione<br />
-t [lista_tty] Seleziona per tty<br />
-u [lista_utenti] Mostra solo i processi relativi agli utenti in lista_utenti, se non specificato all'utente corrente.<br />
x Mostra i processi di sistema (il tty è criptato)<br />
u Mostra informazioni accessorie rispetto al normale ps<br />
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND<br />
silvia 2532 0.0 0.1 21824 4364 pts/1 Ss 13:33 0:00 bash<br />
silvia 2590 6.1 0.0 5872 608 pts/1 T 13:33 1:06 yes<br />
silvia 2657 0.0 0.0 16872 1264 pts/1 R+ 13:51 0:00 ps u<br />
USER: utente che ha lanciato il processo<br />
PID: Process ID<br />
%CPU: (tempo di CPU a carico del processo)/(tempo di CPU totale)<br />
%MEM: (memoria a carico del processo)/(memoria totale)<br />
VSZ: Virtual Size, quantità di memoria virtuale a carico del processo, espressa in byte<br />
RSS: Resident Size, espressa in byte<br />
TTY: Teletype (terminale)<br />
STAT: caratteri che indicano lo stato del processo<br />
R = running; Ss = sleeping interrompibile; D = sleeping non interrompibile; Z = zombie; X =<br />
dead; T = treased o stopped; W = non residente in memoria; < = alta priorità<br />
START: orario di inizio del processo<br />
TIME: tempo di CPU utilizzato dal processo<br />
COMMAND: nome comando<br />
silvia@ubuntu:~$ ps -u silvia -o pid,ppid,%cpu,%mem<br />
$ ps au<br />
$ ps aux<br />
$ ps aur<br />
$ ps ax | head -n 10 Visualizza i processi utilizzando la notazione BSD<br />
PID TTY STAT TIME COMMAND<br />
1 ? Ss 0:02 /sbin/init<br />
2 ? S< 0:00 [kthreadd]<br />
3 ? S< 0:00 [migration/0]<br />
4 ? S< 0:03 [ksoftirqd/0]<br />
5 ? S< 0:00 [watchdog/0]<br />
6 ? S< 0:00 [events/0]<br />
7 ? S< 0:00 [khelper]<br />
46 ? S< 0:00 [kintegrityd/0]<br />
48 ? S< 4:46 [kblockd/0]<br />
Esercizi<br />
1. Ordina i processi in esecuzione sul sistema in base al nome utente.<br />
2. Elencare tutti i processi in esecuzione sul sistema che hanno TTY pari a ?.<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 42
pstree<br />
Permette la visualizzazione ad albero dei processi<br />
SINTASSI: $ pstree [opzioni]<br />
Opzioni:<br />
-h Evidenzia il percorso fino al processo corrente<br />
-p Mostra il PID<br />
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
top<br />
Mostra dinamicamente una serie di informazioni sui processi e sul sistema. Lo stato dei processi sulla macchina<br />
viene aggiornato ad intervalli regolari.<br />
SINTASSI: $ top<br />
(con q si esce dal top).<br />
Nella parte superiore sono presenti informazioni generali sul sistema.<br />
TOP: orario di ultimo aggiornamento (consente di capire ogni quanto avviene l'aggiornamento);<br />
UP: da quanto tempo è acceso il sistema;<br />
USER: numero di utenti connessi;<br />
LOAD AVERAGE: carico medio della macchina in termini di utilizzo di CPU calcolato per intervalli di 15<br />
min, 5 min, 1 min;<br />
N. TASK: totali e per stato;<br />
% UTILIZZO CPU: da parte di US (utente), SY (sistema), etc.;<br />
MEMORIA: quantità totale e utilizzata/libera/buffer<br />
SWAP: quantità totale e utilizzata/libera/cached<br />
user@ubuntu:~$ top<br />
top - 12:31:19 up 7:12, 2 users, load average: 1.64, 1.45, 1.36<br />
Tasks: 116 total, 4 running, 112 sleeping, 0 stopped, 0 zombie<br />
Cpu(s): 2.7%us, 1.7%sy, 0.0%ni, 33.2%id, 62.5%wa, 0.0%hi, 0.0%si, 0.0%st<br />
Mem: 514296k total, 493048k used, 21248k free, 136620k buffers<br />
Swap: 0k total, 0k used, 0k free, 153360k cached<br />
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND<br />
1983 root 15 -5 0 0 0 D 3.7 0.0 15:26.3 kjournald<br />
6059 root 20 0 42320 14m 7376 S 3.7 3.0 1:29.96 Xorg<br />
48 root 15 -5 0 0 0 S 1.3 0.0 5:00.52 kblockd/0<br />
5938 mythtv 20 0 69804 7844 5044 D 1.3 1.5 5:13.02 mythbackend<br />
6541 user 20 0 45252 14m 8428 S 0.7 2.9 0:01.26 gnome-settings-<br />
6633 user 20 0 30156 15m 10m S 0.7 3.0 0:39.56 vmware-user-loa<br />
16217 user 20 0 98.8m 25m 12m R 0.7 5.0 0:07.76 gnome-terminal<br />
4974 root 20 0 13808 2820 2288 R 0.3 0.5 0:28.42 vmtoolsd<br />
5492 mysql 20 0 125m 17m 5188 S 0.3 3.5 1:00.04 mysqld<br />
1 root 20 0 3056 1888 564 S 0.0 0.4 0:02.00 init<br />
2 root 15 -5 0 0 0 S 0.0 0.0 0:00.00 kthreadd<br />
3 root RT -5 0 0 0 S 0.0 0.0 0:00.00 migration/0<br />
4 root 15 -5 0 0 0 S 0.0 0.0 0:03.76 ksoftirqd/0<br />
5 root RT -5 0 0 0 S 0.0 0.0 0:00.00 watchdog/0<br />
6 root 15 -5 0 0 0 R 0.0 0.0 0:00.62 events/0<br />
NI (nice).<br />
Il valore di nice rappresenta un meccanismo di correzione della priorità statica; è un numero intero positivo o<br />
negativo che misura la correttezza dell'algoritmo di scheduling e cerca di spostare i processi CPU bound o I/O<br />
bound. Ad esempio, un fattore ni = +19 abbassa la priorità; ni = -5 alza la priorità.<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 43
Background e foreground<br />
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
Normalmente la <strong>shell</strong> esegue i comandi dell'utente in foreground, ovvero restituisce il controllo del terminale<br />
soltanto a comando terminato. Utilizzando il simbolo & subito dopo un comando, il comando viene eseguito in<br />
background e la <strong>shell</strong> restituisce subito il controllo del terminale. Se non rediretto in file, il comando in<br />
background utilizza il terminale per lo standard output e lo standard error.<br />
$ ls -R /usr > ~/elenco &<br />
[1] 3347 (rappresentano [jobnumber] PID)<br />
Quando viene lanciata una pipeline in background vengono mostrati il numero di job in background sulla<br />
macchina e il PID dell'ultimo processo della pipeline. In maniera informale un job è definibile come un'attività<br />
derivata da un comando dato attraverso una <strong>shell</strong>.<br />
Un processo eseguito in foreground interagisce in maniera diretta con l'utente (browser, editor di testo).<br />
Un processo in background è invece un processo che non interagisce direttamente con l'utente e tipicamente<br />
fornisce un servizio non direttamente visibile all'utente (servizio di sistema, demone). La gestione del<br />
background abilita il multitasking.<br />
yes<br />
Stampa il carattere “y”, o la stringa specificata indefinitamente sullo standard output, finché non viene terminato.<br />
SINTASSI: $ yes [stringa]<br />
Notare la differenza di esecuzione in foreground e background:<br />
$ yes > /dev/null<br />
$ yes > /dev/null &<br />
/dev/null è un black hole, un cestino senza fondo. Si usa quando c'è un output ripetuto che non interessa<br />
all'utente.<br />
sleep<br />
Sospende la <strong>shell</strong> per i secondi specificati.<br />
SINTASSI: $ sleep num_secondi<br />
$ sleep 20<br />
pwd<br />
ls -l<br />
echo è tardi<br />
wait<br />
Sospende l'esecuzione del processo padre di quello passato in argomento, finché quello in argomento non<br />
termina l'esecuzione. Il comando viene usato per forzare il controllo dell'output del figlio prima che riparta il<br />
processo padre. Senza argomento, sospende il padre finché non terminano tutti i figli. Per uscire dal wait si<br />
utilizza Ctrl+C.<br />
SINTASSI: $ wait [PID]<br />
$ sleep 20 &<br />
[1] 2972<br />
$ wait 2972<br />
jobs<br />
Mostra i processi attualmente in background.<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 44
SINTASSI: $ jobs [opzioni]<br />
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
Opzioni:<br />
-l Visualizzazione estesa delle informazioni di ogni processo di stato<br />
-p Mostra solo il PID del processo leader del job selezionato<br />
user@ubuntu:~$ jobs<br />
[1]+ Running sleep 15 &<br />
user@ubuntu:~$ jobs -l<br />
[1]+ 17245 Running sleep 15 &<br />
user@ubuntu:~$ jobs -p<br />
17245<br />
fg<br />
Porta in foreground un job che prima era in background. Se non viene specificato il job su cui agire, riporta in<br />
foreground l'ultimo processo lanciato in background.<br />
SINTASSI: $ fg [num_job]<br />
$ fg 1<br />
Ctrl+Z sospende il processo attualmente in foreground o tutti i processi della pipeline, restituendo il controllo<br />
alla <strong>shell</strong>. Il job in questione viene messo in background.<br />
bg<br />
Permette di far riprendere in background l'esecuzione di un job sospeso, se il job in questione non è in<br />
attesa di un input o di poter emettere l'output. Senza argomento riporta in background l'ultimo job<br />
sospeso.<br />
SINTASSI: $ bg [num_job]<br />
$ yes > /dev/null &<br />
[1] 2590<br />
$ fg 1<br />
yes > /dev/null<br />
Ctrl+Z<br />
[1]+ Stopped yes > /dev/null<br />
$ bg 1<br />
[1]+ yes > /dev/null &<br />
Provate ad eseguire la stessa sequenza di comandi senza redirigere l'output di yes. Cosa accade?<br />
Ctrl+C termina il processo o la pipeline attualmente in esecuzione in foreground.<br />
Segnali<br />
I segnali sono interrupt software che forniscono una tecnica rudimentale di comunicazione asincrona tra<br />
processi. I segnali ci consentono di gestire eventi asincroni quali ad esempio:<br />
- un utente che interrompe l'esecuzione di un programma utilizzando Ctrl+C;<br />
- la fine prematura di un processo in una pipeline.<br />
I segnali costituiscono un insieme ben definito ed a ciascuno di essi è associata una costante simbolica ed un<br />
intero positivo. I sistemi Linux prevedono 64 segnali diversi:<br />
1-31: segnali standard;<br />
32-63: segnali “real-time”;<br />
0: utilizzato per controllare se si hanno i permessi sufficienti per inviare un segnale ad un processo.<br />
Le costanti simboliche hanno tutte il prefisso SIG, sono definite nell'header signal.h e descritte nella pagina di<br />
manuale signal(7).<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 45
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
Distinguiamo le seguenti categorie di segnali in base alla loro origine:<br />
- Segnali provenienti dal terminale: generati quando l'utente utilizza alcune combinazioni di tasti quali Ctrl+C<br />
(SIGINT) o Ctrl+Z (SIGSTOP).<br />
- Segnali derivanti da eccezioni hardware: generati dall'hardware quando si verificano eventi quali la divisione<br />
per 0 o il tentativo di accesso ad un'area di memoria non valida; gli eventi vengono rilevati dal kernel che invia il<br />
segnale corrispondente al processo che ha causato le eccezioni (ad esempio SIGSEGV).<br />
- Segnali provenienti dalla funzione kill(2) (e dal comando kill(1)) kill verso un determinato PID.<br />
- Segnali collegati ad eventi software: generati quando accade un evento di cui un processo deve essere<br />
informato; è il caso, ad esempio, di un processo che scrive in una pipeline mentre il processo che legge è già<br />
terminato (set | less); in tale ipotesi il primo riceve un segnale SIGPIPE quando il secondo termina.<br />
La generazione di un segnale e la sua notifica passano attraverso il kernel che li gestisce utilizzando una coda di<br />
segnali pendenti. La notifica è un evento asincrono rispetto alla generazione e dipende dal kernel. Sui sistemi<br />
Linux un segnale standard (non real time) viene inserito nella coda dei segnali pendenti solo se non è già<br />
presente. In pratica inviando n volte lo stesso segnale standard ad un processo: la prima istanza viene inserita in<br />
coda, mentre quelle successive vengono scartate fintanto che la prima è in coda.<br />
Il processo che riceve il segnale può decidere di gestirlo in 3 modi:<br />
- ignorare il segnale;<br />
- catturare il segnale specificando una funzione detta signal handler da eseguire;<br />
- eseguire l'azione di default associata al segnale (molto spesso la terminazione del processo).<br />
I segnali SIGKILL (9) e SIGSTOP (19) non possono essere né catturati né ignorati ma eseguono sempre l'azione<br />
di default. Le azioni di default sono specificate nella pagina di manuale signal(7).<br />
Regole di protezione: per inviare un segnale utilizzando la system call kill (ed il comando kill) è necessario che<br />
l'uid (real o effective) del processo mittente sia uguale all'uid (real o effective) del processo destinatario. L'utente<br />
root può inviare segnali a tutti i processi.<br />
kill<br />
Il comando kill permette di inviare un segnale ad un processo, indicando direttamente il PID del processo. Se<br />
non si specifica nessun segnale viene inviato SIGTERM (15), che è catturabile.<br />
SINTASSI: $ kill [opzioni] [PID]<br />
Opzioni:<br />
-s nome_segnale Invia il segnale nome_segnale al processo con #id PID<br />
-nome_segn<br />
-num_segn<br />
-l Elenca tutti i segnali ed i loro valori numerici (64 diversi segnali)<br />
$ kill -SIGINT 1722<br />
$ kill -INT 1722<br />
$ kill -2 1722<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 46
CORSO DI FONDAMENTI DEI SISTEMI OPERATIVI<br />
A.A. 2012-2013<br />
(Prof. G. Piscitelli)<br />
pkill<br />
Consente di inviare un segnale ad un processo specificando il nome del programma piuttosto che il pid.<br />
$ pkill -9 a.out<br />
Invia il segnale SIGTERM a tutte le istanze di a.out a cui l'utente ha il permesso di inviare segnali.<br />
killall<br />
Si comporta esattamente come il comando kill ma non riceve come argomento uno o più PID. Come il comando<br />
kill, se non è specificato nessun segnale di default esso è SIGTERM (15).<br />
SINTASSI: $ killall [opzioni] [nome_proc]<br />
Opzioni:<br />
-u [utente] Manda il segnale di terminazione a tutti i processi relativi all'utente specificato.<br />
-i Chiede conferma prima di inviare il segnale, processo per processo.<br />
-nome_segn<br />
-num_segn<br />
$ killall gdm<br />
Termina tutti i processi della sessione grafica, questi infatti sono tutti figli del processo gdm.<br />
Terminazione di un processo<br />
Un processo single-threaded può terminare l'esecuzione normalmente in 3 modi:<br />
- eseguendo return dalla funzione main;<br />
- invocando la funzione exit;<br />
- invocando la system call _exit o la funzione _Exit;<br />
oppure non normalmente in 2 modi:<br />
- invocando la system call abort che genera SIGABRT;<br />
- ricevendo un segnale che ne causa la terminazione.<br />
Lo stato di terminazione può essere definito dall’utente utilizzando return o exit e varianti o assegnato dal kernel,<br />
se l’utente non lo fa esplicitamente o in caso di terminazione con errore.<br />
Fino a quando il genitore non preleva le informazioni sulla terminazione del figlio questi assume lo stato di<br />
zombie ed il PID del processo rimane utilizzato (visualizzabile con ps).<br />
Quando un processo termina prima dei suoi figli, gli orfani diventano figli del nonno o di init, che preleva lo<br />
stato di terminazione di ogni figlio terminato per consentire al kernel di rilasciare i descrittori di processo.<br />
Il diagramma descrive il tipico ciclo di vita di un processo dalla sua creazione alla sua terminazione.<br />
Esercitazioni comandi <strong>shell</strong> <strong>Bash</strong> (Ing. S. Giannini) Pagina 47