Le definizioni esistenti di sistema operativo sono diverse.
Per kernel del sistema operativo intendiamo la parte più “interna” del sistema operativo che, da un lato, controlla l’hardware su cui e’ in esecuzione e, dall’altro, fornisce ai processi che lo utilizzano servizi per accedere all’hardware sottostante. In senso stretto il sistema operativo coincide con in kernel.
L’accesso ai servizi del kernel avviene attraverso l’invocazione di system call, uno strato software di funzioni che forniscono una interfaccia tra le applicazioni ed il kernel. Le “librerie” di sistema sono basate sulle system call ma le applicazioni possono invocare le funzioni definite librerie o direttamente le system call.
La shell è una applicazione che consente l’interazione tra l’utente ed il sistema operativo.
Una definizione meno restrittiva definisce il sistema operativo l’insieme del kernel e delle applicazioni di “base”, quali compilatori, editor, interfacce utente, utility di sistema etc.
Sebbene sia ampiamente utilizzata la seconda definizione, è bene ricordare che il nome Linux identifica il Kernel del sistema operativo.
Essendo i sistemi Unix multi-utente, è necessario che forniscano strumenti per la protezione dei dati di un utente dall’accesso non autorizzato di altri utenti. Ad ogni utente è associata una username ed una password che consentono la sua identificazione in una fase iniziale di riconoscimento nota come fase di login.
Le informazioni su tutti gli utenti di un sistema sono contenute, tipicamente, nel file /etc/passwd
che, per ogni utente, contiene un record in cui sono memorizzate:
/etc/shadow
pur mantenendo, al posto della password una “x” in passwd.Dopo aver inserito username e password, il sistema operativo verifica che le informazioni corrispondano a quelle memorizzate (localmente o meno) nel file delle password ed, in caso affermativo, esegue la shell associata alla username presentata.
Una shell è un interprete di righe di comando che legge gli input dell’utente ed esegue comandi. Esistono diverse shell, che si differenziano sostanzialmente per l’interfaccia con l’utente. In molti casi, il sistema esegue una interfaccia grafica da cui è possibile eseguire una o più shell.
La quasi totalità dei sistemi Unix esistenti fornisce agli utenti una interfaccia grafica “user-friendly”. Per ottenere una finestra testuale è sufficiente eseguire una applicazione che prende nomi diversi a seconda del sistema, come ad esempio “Terminal Window” o “xterm”, o piu’ semplicemente “terminal”.
Il file system di Unix è una disposizione gerarchica di file e directory il cui livello più alto, noto come directory root (o radice), è identificato dal carattere /.
Una directory è un file che contenente directory entries. Ogni entry è’ associata ad un file all’interno della directory e contiene, oltre al nome del file, altre informazioni come ad esempio il tipo di file, (regolare, directory, pipe, etc.), la sua dimensione, una specifica di quali utenti hanno accesso al file, e così via.
In linea di principio, i nomi di file possono essere composti da qualsiasi sequenza di caratteri che non contenga il carattere / od il carattere nullo. In realtà, si restringe in charset utilizzabile ad un sottoinsieme dei soli caratteri “visualizzabili”.
Quando viene creata una nuova directory, vengono automaticamente create al suo interno due “sottodirectory” speciali chiamate . (punto) e .. (punto-punto).
La prima è un riferimento alla directory corrente mentre la seconda è un puntatore alla directory padre. L’utilità di queste due directory speciali sta nel fatto che consentono di definire percorsi “relativi” all’interno del filesystem.
Ad ogni processo è sempre assegnata una “directory corrente”, che indica la directory in cui il processo opera di default.
Come abbiamo visto, il file passwd contiene la “home directory” di ogni utente che indica la directory corrente utilizzata dalla shell all’atto del login.
La directory corrente può essere modificata utilizzando il comando shell cd o la system call chdir.
Tutte le varianti dei sistemi Unix, implementano I seguenti criteri per definire la topologia del proprio file system:
Per ogni processo esiste un’unica root directory. Tutte le altre directory sono discendenti dell’unica root presente. In genere tutti i processi condividono la stessa directory radice. La struttura definita dalle directory, quindi, è “simile” ad un albero.
È possibile, come vedremo, creare collegamenti tra diversi rami dell’albero. La struttura reale è, quindi, un grafo.
In Unix, a differenza di Windows, non esiste il concetto di “disco”. La radice del filesystem presente su un disco viene connessa all’unico filesystem presente sul sistema diventando sottodirectory di una directory presente.
Esistono directory di sistema, sottodirectory della root, che si ritrovano in tutti i sistemi Unix-like:
Una sequenza di uno o più filename divisi da / definisce un pathname. Un pathname che inizia per / è detto assoluto, altrimenti è detto relativo.
Un pathname assoluto identifica il percorso per raggiungere il file, partendo dalla root del filesystem. Affinché il pathname corrisponda ad un file è necessario che i filename compresi tra il primo e l’ultimo “/” devono corrispondere a directory. Ad esempio: la stringa “/home/lso/lezione1.ppt
” corrisponde ad un pathname corretto se:
Un pathname relativo identifica il file a partire dalla directory corrente. Ad esempio, il pathname “lso/lezione1.ppt” corrisponde ad un file se:
I sistemi Unix consentono la protezione delle directory e dei file in esse contenuti attraverso il seguente sistema:
Per visualizzare le informazioni associate ad un file od una directory è possibile utilizzare il comando “ls”, specificando l’opzione “-l”. Un esempio di output è riportato di seguito.
-rw-rw-r-- 1 lso users 591 2009-12-10 10:16 a.txt
-rwxr-xr-x 1 lso users 396 2009-12-12 18:07 b.sh
drwxr-xr-x 2 lso users 48 2009-11-22 16:22 TEST
L’esempio mostra l’elenco dei tre file contenuti “ls -l”.
Le informazioni riguardanti ogni singolo file vengono riportate sulla stessa riga.
La prima colonna identifica il tipo di file e le protezioni.
La seconda colonna indica il numero di link a quel file.
La terza colonna riporta il nome del proprietario del file (lso in tutti I casi).
La quarta colonna indica il nome del gruppo (users in tutti I casi).
La quinta colonna indica la dimensione del file.
La sesta e la settima colonna indicano, rispettivamente, la data e l’ora di ultima modifica del file.
L’ultima colonna riporta il nome del file.
Analizziamo in particolare la prima colonna:
-rwxrw-r-- 1 lso users 591 2009-12-10 10:16 a.txt
-rwxr-xr-x 1 lso users 396 2009-12-12 18:07 b.sh
drwxr-xr-x 2 lso users 48 2009-11-22 16:22 TEST
La prima colonna consiste di 10 caratteri.
Analizziamo in particolare la prima colonna:
-rwxrw-r-- 1 lso users 591 2009-12-10 10:16 a.txt
-rwxr-xr-x 1 lso users 396 2009-12-12 18:07 b.sh
drwxr-xr-x 2 lso users 48 2009-11-22 16:22 TEST
I 9 caratteri successivi identificano le protezioni.
Il significato del flag di protezione assumono un significato leggermente diverso per le directory.
Il flag “x” associato ad una directory consente di “accedere ai file in essa contenuti”.
Per “accedere” si intende qualsiasi tipo di accesso, I.e., lettura, scrittura ed esecuzione.
L’assenza del flag “x”, ad una directory, quindi, rende l’accesso a tutti I file contenuti nell’intero “sotto-albero” in essa radicato in molti casi inutilizzabile.
È errore comune modificare le protezioni di una directory non settando il flag x almeno per il proprietario.
Si noti che è possibile impostare per una directory I permessi –x–x–x. In questo caso:
Di seguito riportiamo alcuni comandi unix per la manipolazione di file e directory. Per ognuno dei comandi unix è sempre possibile ottenere un help attraverso il comando man, utilizzando la sintassi man comando.
Le operazioni di I/O sono precedute dall’apertura di un canale di comunicazione.
Nei sistemi Unix tutto può essere visto come un file. Il sistema operativo fornisce una interfaccia uniforme per l’accesso ai file su disco, ai device, ai canali di comunicazione tra processi sullo stesso calcolatore/su calcolatori diversi.
Ad ogni “file” viene associato un file descriptor, un interno non negativo, che viene utilizzato dal processo per leggere e/o scrivere dal file.
Per convenzione tutte le shell aprono sempre tre canali di comunicazione noti come standard input, standard output e standard error, associati rispettivamente ai file descriptor 0, 1 e 2. Per default, questi tre canali sono sempre associati al terminale corrente, I.e. lo standard input corrisponde alla “tastiera”, gli standard output ed error alla “finestra” associata alla shell.
È possibile modificare l’associazione di questi file descriptor “redirigendoli” su altri file (siano essi file su disco, device o canali di comunicazione).\
Un programma è un file “eseguibile” su disco.
Un processo è un programma in esecuzione.
Ad ogni processo il kernel assegna un identificativo univoco noto come Processi Identifier o PID.
I processi possono essere eseguiti in due modalità:
Un processo in foreground può essere sospeso utilizzando la combinazione di tasti CTRL+Z.
Un processo In foreground può essere terminato utilizzando la combinazione di tasti CTRL-C
Per visualizzare I processi in esecuzione è possibile utilizzare il comando ps.
Il comando pstree consente di visualizzare tutti I processi dell’utente che lo esegue, sotto forma di “albero”. Un processo A è figlio di un processo B nell’albero se A è stato creato dal processo B.
Per terminare un processo in esecuzione è possibile utilizzare il comando kill specificando il pid del processo da terminare.
1. Introduzione ai sistemi Unix
2. Principi di programmazione Shell
3. Esercitazioni su shell scripting - parte prima
5. Esercitazioni su shell scripting - parte seconda
6. Espressioni Regolari ed Introduzione ad AWK
7. Esercitazioni su espressioni regolari ed awk scripting
9. Esercitazioni su awk scripting - parte seconda
10. Programmazione in linguaggio C: Input/Output di basso livello
11. Esercitazioni su I/O di basso livello
12. Interazione con file di sistema e variabili d'ambiente
13. Esercitazioni sulla gestione dei file di sistema e le variabili...
14. System call per la gestione di file e directory
15. Esercitazioni su gestione file e directory
16. La programmazione multi-processo
17. Esercitazioni su programmazione multi-processo
18. I Segnali
20. I Socket
Introduction to linux: A hands on guide. Capitoli 1-4