Il Sistema Operativo Unix

  1. Un po' di Storia
  2. Generalita' su UNIX
  3. I File in Unix
  4. Protezioni
  5. Comandi per lavorare su Rete

Un po' di Storia ( indice )

Linux e Minix, che analizzaremo in questo corso, sono S.O. Unix-like.
Unix e' nato nel 1969-70, su iniziativa di Ken Thompson e Dennis Ritchie dopo l'abbandono del progetto Multics, nei laboratori AT\T (Bell Labs). sono stati scritti usando il linguaggio C.

A parte il piccolo nucleo, scritto in assembler, tutto il resto e' in linguaggio C, che rende il sistema altamente indipendente dall'hardware. La nuova filosofia e': piccolo e' bello.

Attualmente "UNIX" e' un trade mark della USL (Unix System Labs.) della Novell. Altre case mettono a disposizione implementazioni (a pagamento) di Unix: SunOS (Sun Micr.), AIX (IBM), Ultrix, OSF (DEC).

Inoltre POSIX e' uno standard di Unix.

Esistono due filoni di Unix:

che si sono intrecciati piu' volte.
Inizialmente Unix e' stato istallato su calcolatori Digital (DPD11 e VAX), quindi su Sun (versione BSD) e su macchine IBM, Silicon Graphics ecc. (versione SystemV, da USG). Si sono formati vari consorzi per la gestione di Unix: dal 1987 al 1991, AT&T e Sun Micr. hanno lavorato congiuntamente, dal 1988 al 1991 il consorzio IBM, DEC, HP ha collaborato per la formazione della Open Software Foundation.

Un passo importante e' stato fatto a partire dal 1984, anno in cui il MIT sviluppa il sistema X. Unix + X-Window System continueranno insieme. Successivamente la Microsoft uscira' con un prodotto simile: il NeWS (Network extensible Window System).
La versione attualmente in uso e' X versione 11.

Il codice di Unix e' stato disponibile e gratuito dall'inizio fino alla versione 7. Attualmente e' disponibile con licenza gratuita il codice di Linux.

Caratteristiche principali:

Altre caratteristiche:

Generalita' su UNIX ( indice )

Lo scopo di Unix e' fornire un insieme di primitive (funzioni) per la gestione dei processi e dei file. Ovviamente le funzioni sono utilizzabili solo internamente ad un programma, e cio' porrebbe dei problemi all'utilizzatore, che ha invece bisogno di interagire con il sistema tramite comandi. Per consentire un uso interattivo di Unix, sono stati quindi definiti dei comandi: per ogni comando esiste un programma (da una a migliaia di istruzioni) che, utilizzando le primitive di Unix, eseguono la richiesta.

In questa sezione si parlera' di Unix dal un punto di vista dell'utente che utilizza unicamente i suoi comandi. Nella sezione 3 si vedranno invece alcune delle principali funzioni Unix, come possono essere utilizzate all'interno di programmi C, e qual'e' la struttura dati interna di Unix.
Si potra' notare come ci sia una certa somiglianza fra alcuni comandi e alcune funzioni, che hanno in comune anche l'identificatore (ad esempio chmod, per cambiare i privilegi dei file, o ls per listare le directory), ma esistono anche comandi che non hanno una corrispondenza diretta con nessuna funzione (ad esempio per cancellare un file si usa il comando rm o remove, ma non esiste nessuna funzione rm: il motivo sara' spiegato nella parte Cancellazione di file).
Inoltre i comandi hanno generalmente molte opzioni per dirigerne il loro funzionamento, mentre le funzioni hanno generalmente un insieme limitato e semplice di parametri di chiamata.

Si pone a questo punto il problema: come si fa ad attivare almeno per la prima volta un programma su Unix? Lo fa Unix stesso, che attiva il processo init, dal quale poi deriva attraverso vari passaggi il processo shell, che legge un comando da tastiera (o dal file indicato dall'utente), lo interpreta, e provvede ad eseguirlo, mandando in esecuzione il programma che lo implementano. Dettagli maggiori su questi punti si trovano nella sezione 3.

Esistono diverse versioni del programma shell; csh, tcsk, ksh, bash ecc. Volendo, si puo' scrivere la propria "shell". La shell accetta dall'utente dei comandi che devono essere scritti utilizzando un linguaggio specifico. Vedremo in seguito (sezione 4) il linguaggio della shell bash.

Un comando e' quindi un programma qualunque, l'unica differenza e' che il "possessore" di questi programmi e' il superuser, che ha privilegi non posseduti dallo user "normale" (ricordiamo che Unix e' multiutente, e che ogni utente ha delle limitazioni e delle autorizzazioni sulle operazioni che puo' compiere). Nel capitolo successivo si capira' meglio cosa si intende per privilegi.

Quando si richiede l'esecuzione di un comando (o di un qualunque programma utente) la shell ricerca l'eseguibile in una o piu' directory, che possono essere indicate dall'utente stesso, elencandole in una variabile gestita dalla shell, il PATH (vedere sezione 4). Non tutti i comandi sono pero' comandi Unix, cioe' programmi. Alcuni sono comandi gestiti direttamente dalla shell (ad esempio cd, fg, bg, pwd).

Ogni utente ha una login riservata, con collegata passwod codificata. Esistono due tipi di utente: superuser (con i massimi privilegi) e user.
Quando ci si collega con Unix viene richiesta la login e successivamente la password, che non viene visualizzata per motivi di sicurezza.
La password si puo' cambiare con il comando passwd (vedi spiegazioni poco sotto).

Per uscire da una sessione si usa il comando logout oppure la combinazione di tasti ctr alt del (potrebbe funzionarne anche solo uno),

Nel kit di istallazione di Unix e' compreso un insieme di manuali in linea.
E' diviso nei segenti settori numerati:

  1. Comandi per gli utenti normali,
  2. Funzioni del kernel, da inserire in un programma,
  3. Funzioni per la programmazione in C,
  4. File speciali per la gestione dei device hardware,
  5. File di sistema relativi all'amministrazione,
  6. Giochi e programmi dimostrativi,
  7. altri, non classificati,
  8. Comandi per l'amministrazione

Il comando per consultare una voce del manuale e' man.

ESEMPIO 2.1
man passwd
provoca la scrittura della pagina relativa alla funzione passwd(1).

PASSWD(1)           Linux Programmer's Manual           PASSWD(1)
NAME
       passwd - change password
SYNOPSIS
       passwd [ name ]

DESCRIPTION
       passwd  will  change  the specified user's password.  Only
       the superuser is allowed to change other user's passwords.
       If the user is not root, then the old password is prompted
       for and verified.

       A new password is prompted for twice, to avoid typing mis-
       takes.  Unless the user is the superuser, the new password
       must have more than six characters, and must  have  either
       both  upper  and lower case letters, or non-letters.  Some
       passwords which are similar to the  user's  name  are  not
       allowed.

FILES
       /etc/passwd
       /etc/shells

SEE ALSO
       chsh(1), chfn(1)

BUGS
       A password consisting of all digits is allowed.
       No  warnings  are  printed if the superuser chooses a poor
       password.
       The -f and -s options are not supported.

AUTHOR
       Peter Orbaek (poe@daimi.aau.dk)

Linux 1.0                  22 June 1994                         1

Altri comandi per consultare il manule:
apropos + nome del comando e whatis + parola chiave.

I File in Unix ( Indice )

Come in qualunque sistema operativo, anche in Unix dati e codice sono memorizzati su file (sequenza di byte). Ogni file ha un nome seguito eventualmente da un estensione, che viene normalmente utilizzata per indicare il tipo del file.
I file sono raggruppati in directory.

In Unix l'attivita' di I/O e' resa trasparente all'utente tramite il concetto di file.

Esistono 3 tipi di file:

File Directory

Sono utilizzati per raggruppare i file e sono organizzate ad albero.

Un file e' individuato dal suo nome specifico, e dal cammino (path name) che bisogna fare nell'albero delle directory per arrivare a lui. Il cammino e' indicato a partire dalla radice (indicata con il solo carattere /) con i vari nomi delle directory attraversate separate fra loro dallo stesso carattere /.
Il path name specifica quindi la posizione del file nell'albero delle directory (attenzione: Unix distingue fra lettere minuscole e maiuscole).

Figura 2.1

Eempio
/user/SysOp/Esame
specifica la posizione del file "Esame" a partire dalla radice (pathname assoluto).

Poiche' sarebbe faticoso scrivere sempre tutto il path, che potrebbe essere lungo, si utilizza il concetto di Working Directory (WD) . E' possibile posizionarsi ad un certo punto dell'albero delle directory (con il comando cd), e da quel momento in poi i nomi dei file possono essere dati in modo relativo a quella directory. In questo caso il nome non inizia con il caratter "/".
La WD e' gestita dalla shell, che provvede anche ad estendere i nomi relativi dei file in assoluti, prima di effettuare le chiamate alle primitive Unix.

Il comando di shell pwd provoca la scrittura della working directory corrente (vedere esempio 2.2).

Al momento del login viene automaticamente aparta una WD detta home directory, che per il superuser e' la root "/". La home directory e' decisa dall'amministratore del sistema per ogni utente. Il ramo dell'albero delle directory che parte dalla home directory e' considerato riservato per quell'utente, che puo' proteggere i suoi file come vuole (attenzione, il superuser ha comunque sempre tutti i Privilegi!).

La shell riconosce alcuni caratteri a cui da' un significato preciso. Fra gli altri qui ricordiamo:

           .       indica la directory corrente 
           ..      indica la directory genitore 
           ~       indica la home directory 

Con il comando "cd nomedirectory" si puo' cambiare working directory.

ESEMPIO 2.2

Vediamo quali sono normalmente le directory usate da Unix per i suoi programmi. Anche in questo caso occorre dire che la divisione non e' obbligatoria, ma e' comunque adottata da quasi tutti i sistemi.

/          Directory generale del sistema, detta "root" 
/bin       Contiene i comandi piu' importanti per l'utente 
/dev       Contiene i file di accesso ai dispositivi fisici del calcolatore 
           (dischi, memoria, porte seriali e parallele, ... ) 
/lib       Contiene le librerie dinamiche necessarie al funzionamento
           dei programmi 
/etc       Contiene dei file e le sottodirectory per l'amministrazione 
           del sistema 
/tmp       Contiene i file temporanei del sistema e degli utenti 
/var       Contiene sottodirectory con file che tendono a crescere di 
           dimensioni. 
/var/spool Contiene i file di spool temporanei di vari programmi: 
           stampa, mail, ... 
/var/adm   Contiene i file con messaggi del sistema 
/home      Contiene le directory assegnate agli utenti 
/sbin      Contiene i programmi di partenza del sistema 
/usr       Contiene il grosso del sistema operativo. \'E divisa a sua 
           volta in sottodirectory 
/usr/bin   Contiene i comandi di base
/usr/sbin  Contiene i comandi di amministrazione del sistema 
/usr/include Contiene gli header file per la programmazione C e quindi 
           per la creazione del kernel 
/usr/man   Contiene i manuali 
/usr/lib   Contiene le librerie per la programmazione e file di 
           supporto per molti programmi 

Per creare una nuova directory si usa il comando mkdir nome_nuova_directory.

Come listare file

I file si possono listare con il comando ls piu' varie opzioni.

ls lista i nomi dei file della WD e basta.
ls -l da' una lista lunga dei file della WD, con indicazioni sul tipo e la lunghezza di ogni file.
ls -i da' il valore dell'i-node di ogni file (sara' spiegato successivamente cos'e' un i-node).
ls -a lista anche i file nascosti, cioe' quelli che cominciano con il carattere ".".
ls -R elenca ricorsivamente i file della WD e le sue sottodirectory.

E' possibile listare i file di altre sottodirectory dandone per argomento il nome. Ad esempio ls /user/SysOp/Esame lista il contenuto della directory indicata.

Le opzioni si possono concatenare, ad esempio ls -la.

ESEMPIO 2.3


disi > ls -l 
total 63
drwxr-xr-x  4 gianuzzi      512 Dec  9  1996 PVMsnap
-rw-r--r--  1 gianuzzi     2817 Apr 22  1996 README
drwxr-xr-x  2 gianuzzi      512 Sep 26  1996 bin
-rw-rw-rw-  1 gianuzzi    12909 Nov 20  1996 device_orig.txt
lrwxrwxrwx  1 gianuzzi       25 Sep 26  1996 ftp -> /ftp/pub/person/GianuzziV
-rw-r--r--  1 gianuzzi    34425 May 14 15:41 history.ps
-rw-rw-rw-  1 gianuzzi     1421 Nov  7  1996 hosts
lrwxrwxrwx  1 gianuzzi       20 Dec  9  1996 pvm3 -> /home/elios/pvm/pvm3
-rw-r--r--  1 gianuzzi      801 Nov 20  1996 sh_mem1.c
-rw-r--r--  1 gianuzzi      413 Nov 20  1996 sh_mem2.c
-rw-r--r--  1 gianuzzi     2486 Nov 22  1996 shell.txt
drwxrwxrwx  3 gianuzzi     1024 Mar 24 23:12 win
lrwxrwxrwx  1 gianuzzi       32 May  6  1996 www -> /home/elios/www/person/GianuzziV

Il comando file da' informazioni sul tipo di file (eseguibile, testo, ecc.). basename nome_file restituisce il nome del file senza l'eventuale path iniziale, mentre dirname nome_file restituisce il path senza l'ultimo nome del file.

File Speciali

L'accesso ai dispositivi hardware avviene attraverso i device file.
Essi sono quindi visibili attraverso le system call per la lettura e scrittura di file.

Sono elencati nella directory /dev.

[ 502 ] arsenio:gianuzzi:~ $ cd /dev
[ 503 ] arsenio:gianuzzi:/dev $ ls -l *|more
.......
crw-rw-rw-   1 root     sys       14,   4 Jul 18  1994 audio
crw-rw-rw-   1 root     sys       14,  20 Jul 18  1994 audio1
brw-rw----   1 root     disk      29,   0 Feb 15  1995 aztcd
.......
brw-rw-rw-   1 root     floppy     2,   0 Apr 28  1995 fd0
brw-rw----   1 root     floppy     2,  36 Apr 28  1995 fd0CompaQ
brw-rw----   1 root     floppy     2,  12 Apr 28  1995 fd0D360
.......
brw-rw----   1 root     disk       3,   0 Apr 28  1995 hda
brw-rw----   1 root     disk       3,   1 Apr 28  1995 hda1
brw-rw----   1 root     disk       3,  10 Apr 28  1995 hda10
brw-rw----   1 root     disk       3,  11 Apr 28  1995 hda11
......

Tutti i file speciali hanno un

In realta' i file speciali esistono solo come entry in una directory. Essi sono poi presenti in una tabella di Unix, che associa ad ogni file un codice, il device driver del dispositivo in questione.
Tutti i device con lo stesso MDN condividono il codice dell'unico driver di quel tipo di dispositivo presente nel sistema. Il numero dell'unita' e' un parametro.

hda              Primo disco fisso IDE 
hda1, hda2 ..    Partizioni disco fisso IDE 
hdb              Secondo disco IDE 
ttyS0, ttyS1 ... Porte seriali input 
cua0, cua1, ...  Porte seriali output (modem) 
lp0, lp1, ...    Porte parallele 
fd0, fd1, ...    Unita' dischetti 
fd0H1440         Unita' dischetti formattata 1.44 MB 
null             Nullo 

L'ultimo device consentere di buttar via l'output e/o l'output degli errori di un programma.

ESEMPIO
krypton > cp /dev/fd0 immagine

copia il contenuto di tutto il floppy nel file immagine. Si possono cosi' fare facilmente copie fisiche di floppy.

Protezioni ( Indice )

Ad ogni file (e ad ogni processo) e' associato:

  1. un proprietario, individuato dallo uid (user identifier) e il gruppo di appartenenza (gid, group identifier) del proprietario,
  2. un insieme di permessi, ognuno rappresentato con un bit, che ne definiscono l'utilizzo.

I permessi sono di tre tipi: lettura (R), scrittura (W), esecuzione (X). Con il permesso di lettura si puo' listare il file, con quello di scrittura si puo' modificarlo, anche azzerarlo, ma non cancellarlo come file. Il permesso di esecuzione permette di eseguirlo, purche' sia un binario eseguibile o uno script.
I possibili utilizzatori sono di tre tipi: il possessore, il gruppo a cui appartiene, tutti gli altri utenti (other).

             R W X            R W X            R W X
             owner            group            world

Per una directory il permesso di lettura consente di listarne il contenuto (ad esempio, usando il comando ls), in scrittura indica la possibilita' di modificare una directory (ad esempio cancellare o creare un file), infine il permesso di esecuzione indica la possibilita' di attraversarla per accedere a sue sottodirectory.

ESEMPIO:
Una directory da' il diritto X e non quello W a other.
Uno dei file listati nella directory da' il permesso W.
Allora un qualunque utente puo' modificare, anche azzerare totalmente il file, ma non puo' cancellarne il nome dalla directory.

Il permesso di scrittura per group (g) e per other (o) e' comunque protetto: si puo' cioe' scrivere sul file, ma non cambiarne gli attributi (ad esempio cambiarne il possessore), in quanto solo il possessore di un file puo' modificare l'i-node del file (ad esempio tramite il comando chmod).
I bit di protezione si applicano anche ai file speciali.

Nella directory lunga dei file compare una lettera prima dei permessi:

        d     directory, 
        l     link simbolico 
        c     file speciale a caratteri 
        b     file speciale a blocchi.

Esistono altri tre bit non listati: sticky bit (Save Text Image), setuid SUID (set user identifier) e setgid SGID (set group identifier).

Lo sticky bit serve per le directory a consentire o no la cancellazione o rinominazione di un file da parte di un utente non proprietario, che abbia comunque il permesso di scrittura su quella directory. Gli altri due, associabili ad un eseguibile, permettono di modificare temporaneamente le protezioni dell'utente che lo esegue.

Ad esempio, quando l'utente esegue un comando, il comando ha come possessore root. L'esecuzione e' possibile anche da parte di un altro utente perche' i comandi danno a tutti il privilegio di esecuzione.
In alcuni casi l'utente che lo esegue assume temporaneamente i diritti del proprietario (root), in modo da poter eseguire una chiamata ad una funzione eseguibile solo in modo superuser (vedi funzione mknod della sezione 3).
Il privilegio e' perso immediatamente dopo l'uscita dal comando.

I bit di protezione sono dunque 2 + 9.

Interpretati con notazione ottale, il valore 1711 indica un file che puo' essere eseguito da tutti, letto e scritto (quindi eventualmente cancellato) solo dal possessore, ed eseguito con i privilegi del possessore da qualunque altro utente.

Si possono cambiare i permessi dei file con il comando chmod.

ESEMPIO
krypton < chmod 440 README
elimina il permesso di scrittura all'owner e di lettura a word.

Ci sono anche le forme abbreviate relative (vedere con il comando man):
ESEMPIO
krypton < chmod o-w README
elimina la possibilita' di scrittura all'owner.

Link fra file

E' possibile indicare lo stesso file fisico con piu' di un nome, attraverso un link simbolico.
Questi file sono listati con il carattere "l" prima dei permessi, inoltre sulla destra compare il nome del file con il simbolo -> seguito dal nome del file a cui e' linkato. Nell'esempio 2.3 (lista lunga) abbiamo tre link:

   ftp  -> /ftp/pub/person/GianuzziV
   pvm3 -> /home/elios/pvm/pvm3
   www  -> /home/elios/www/person/GianuzziV

Si usano ad esempio per comodita'. Nell'esempio, pvm3 contiene una libreria per la comunicazione distribuita usata anche da altri utenti e caricata dal sistemista in una certa directory condivisa. Quest'ultima potrebbe anche essere cambiata, per qualche necessita'. In questo caso basterebbe cambiare il link (cancellare pvm3 e reinserire pvm3 linkato alla nuova directory) senza cambiare niente nei programmi che usano quella directory.

Il comando usato per creare il link fra "ftp" e "/ftp/pub/person/GianuzziV" (la directory esistente) e'
ln -s   /ftp/pub/person/GianuzziV   ftp
L'opzione "-s" specifica che si tratta di un link simbolico, cioe' solo fra i nomi dei file.

Cosa succede se qualcuno cancella il file /ftp/pub/person/GianuzziV ? Non viene segnalato nessun errore finche' qualcuno non usa il file ftp. A questo punto la shell cerca di accedere al file /ftp/pub/person/GianuzziV che non trova, quindi viene dato errore. I due file (la directory su cui si inserisce il link ftp, e /ftp/pub/person/GianuzziV) possono anche essere su supporti fisici diversi.

Il legame insomma esite solo fra nomi di file e non fra nome e file fisico.

E' possibile anche creare un link fisico (hard), per cui si attribuisce piu' di un nome allo stesso file fisico. In questo caso la gestione non viene effettuata dalla shell, ma da Unix stesso, attraverso la funzione link (vedi sezione 3).
Non e' possibile in questo caso effettuare link fra supporti fisici diversi.

Gli hard link non vengono evidenziati nella directory con la lettera l iniziale, perche' accedono direttamente al file, e non ad un altro file identifier. E' invece possibile sapere se un file fisico e' riferito con piu' identificatori, in quanto uno dei campi della lista lunga e' il reference counter dell'i-node del file (unico per ogni file fisico).

Reference counter

Unix utilizza ampiamente la struttura di reference counter.
Un oggetto (file, processo, codice, entry di una tavola del kernel, ecc.) e' associato ad un contatore che conta quanti riferimenti gli sono fatti. Un file fisico ha reference counter = 1 quando viene creato. Il contatore viene incrementato ogni volta che si aggiunge un hard link.

Vediamo un esempio di lista lunga con l'opzione -i, che richiede la scrittura dell'i-node number di ogni file listato.

ESEMPIO 2.4
krypton > ls -li README
102  -rw-r--r--    1  gianuzzi  prof       1267 Apr 22 14:56 README

krypton > ln README READYOU
krypton > ls -li README READYOU
102  -rw-r--r--    2  gianuzzi  prof       1267 Apr 22 14:56 README
102  -rw-r--r--    2  gianuzzi  prof       1267 Apr 22 14:56 READYOU

Inizialmente esiste il file README con ref.counter=1 e i-node number=102.
Poi viene aggiunto il link fisico READYOU (adesso il file con i-node=102 ha due identificatori: README e READYOU).
Nella lista il file 102 compare due volte, con i due nomi, e con ref. counter=2.

Cancellazione file

Per la cancellazione di un file si usa il comando rm nomefile.
Le directory si cancellano con il comando rmdir nomedir, solo se sono gia' vuote, oppure con il comando ricorsivo rm -r nomedir (attenzione!).

krypton > ls -li README READYOU

102  -rw-r--r--    2  gianuzzi  prof       1267 Apr 22 14:56 README
102  -rw-r--r--    2  gianuzzi  prof       1267 Apr 22 14:56 READYOU

krypton > rm READYOU
krypton > ls -li READ*

102  -rw-r--r--    1  gianuzzi  prof       1267 Apr 22 14:56 README

NOTA: un file e' effettivamente cancellato (non piu' raggiungibile) solo quando non ha piu' riferimenti. Nel caso dei file, quando non ha piu' hard link.

Gestione dei File System

Unix vede i file in modo indipendente dal supporto fisico su cui sono scritti. La struttura ad albero delle directory e' presente anche sul supporto su cui i file si trovano. Occorre allora agganciare la radice di questa struttura ad una foglia dell'albero che origina da root.

Figura 2.2

Supponiamo di voler montare il file system contenuto in un floppy disc come sottodirectory di "SysOp", di nome "AA1999". Con il comando

mount    /dev/fd0H1440   /user/SysOp/AA1999 

si esegue quanto voluto.

Il comando mount potrebbe essere disabilitato, cioe' utilizzabile solo dal superuser. Al momento dell'inizializzazione del sistema, sono eseguiti comandi di mount che provvedono a montare eventuali supporti necessari.

Dopo aver montato un supporto, non e' piu' necessario riferirlo per accedere ai file. Ad esempio, per accedere al file fork.c della figura 2.3 e' sufficiente il suo nome: /user/SysOp/AA1999/esercizi/fork.c.

Figura 2.3

Il comando mount da solo consente di avere la mappa di mount (quali supporti sono montati su quali directory). Il comando df da' anche la percentuale di utilizzo. Il comando du nome_file

lista l'utilizzo dello spazio da parte di file e directory in numero di blocchi. La dimensione di un blocco puo' essere di 512 o 1024 byte.

ESEMPIO
krypton > df
Filesystem   512-blocks        Used       Avail Capacity  Mounted on
/dev/rz6a        126462       80556       33258    71%    /
/proc                 0           0           0   100%    /proc
/dev/rz6g        792124      659804       53106    93%    /usr
/dev/rz6h        810952      409752      320104    56%    /usr/local
/dev/rz3c       1011226      792556      117546    87%    /usr/users

E' possibile anche montare file system DOS (o FAT16, non FAT32). Il comando mount -t vfat /dev/fd0 /floppy monta un floppy con FAT16 nella directory /floppy.

Il comando umount consente di smontare un FS, ma solo quando non ci sono attivita' ancora da completare che accedono a quei file. Si deve dare da una directory non derivante da quella da smontare. Si deve solo specificare il device, non la directory: krypton > umount /dev/fd0.

Processi e Demoni

I demoni sono processi, lanciati per lo piu' all'avvio del sistema, che aspettano le richieste dell'utente (stile client-server). Ad esempio il demone lpd aspetta le richieste di stampa date con il comando lpr.
Il comando per avere la lista dei processi e' ps. Senza opzioni vengono listati solo i processi di cui il richiedente e' proprietario, e che sono stati attivati durante la stessa sessione (fra lo stesso login - logout). L'opzione aux consente di avere il listato completo.

ESEMPIO 2.5

disi > ps 

PID     TTY   STAT      TIME       COMMAND

16200      p2   s      0:04.92       -tcsh
16330      p2   R      0:01.87       ps

krypton > ps aux

USER       PID %CPU %MEM   VSZ  RSS TTY      S    STARTED      TIME      COMMAND
root       315  0,0  0,2 1,39M  48K ??       I      gui 19     0:29.26   /usr/sbin/inetd
root       320  0,0  0,0 1,34M   8K ??       I      gui 19     0:05.74   /usr/sbin/cron
root       351  0,0  0,4 1,38M 112K ??       I      gui 19     0:07.55   /usr/lbin/lpd
root       274  0,0  0,4 1,55M 128K ??       I      gui 19     3:22.66   /usr/sbin/snmpd
gianuzzi  5843 20,0  1,7 2,03M 520K ttyp4    S    14.42.18     0:01.48   - (tcsh)
root       376  7,0 10,2 14,1M 3,1M ??       S <    gui 19    04:21:18   /usr/bin/X11/X -nice -2 -auth /usr/var/
gianuzzi  4389  3,0  2,3 9,49M 696K ??       S    09.38.53     0:08.86   /usr/bin/X11/mwm
......

Dove ( con varie opzioni):
User          proprietario del processo  
PID           identificatore del processo  
%CPU, %MEM    Percentuali utilizzo CPU e memoria  
              nell'ultimo minuto  
SIZE          Dimensione del processo  
RSS           KB di memoria occupata  
TTY           Porta seriale associata al programma  
STAT          Stato del processo  
              S=sleeping, R=running, I=idle, Z=zombie  
START         Orario di avvio del processo  
TIME          Tempo utilizzato effettivamente  
COMMAND       Comando con cui e' stato lanciato il processo  

init e' l'unico processo lanciato dal kernel, essenziale in quanto il sistema operativo esegue solo funzioni e non comandi.
I processi della lista il cui nome finisce con "d" sono demoni, mentre getty e' il programma di gestione di accesso al sistema.
Il comando per interrompere un processo in background (vedi sezione 4) e' kill pid dove "pid" e' il process identifier. Ad esempio kill 315 causa, se si hanno i necessari privilegi, la morte del processo 315 (demone gestione rete). Vedere anche funzione kill.

Altri comandi utili sono cp (copia file) e mv (rinomina un file).
Leggere il manuale in linea per le spiegazioni.

Generalita' sulla Shell

E' un programma che fa da intermediario fra l'utente e il kernel. Legge una linea di caratteri e la interpreta attivando i processi come richiesti dall'utente. Esistono diverse shell (sh, csh, tcsh, bash ecc.). La bash (FSF) e' quella normalmente usata in Linux, la shell bash.
Ha un suo linguaggio e utilizza dei file (.profile, .csh, .tcsh ecc.) per l'inizializzazione delle variabili interne.

Esecutore comandi

La shell accetta comandi per Unix dall'utente e li manda in esecuzione, secondo le direttive date. Assegna automaticamente ad ogni programma mandato in esecuzione:

  • lo standard input, cioe' da dove riceve i dati (tastiera),
  • lo standard output, dove deve stampare i risultati (schermo),
  • lo standard error, dove scrive i messaggi d'errore (schermo).
  • Un comando normalmente invia l'output su monitor (ad esempio ls). Come fare se invece si vuole la directory listata su file per poterla ad esempio stampare? Se ne puo' ridirigere l'output. Si usa il linguaggio delle shell che (tutte quante) riconoscono i caratteri ">", "<" e "2>" seguiti dal nome di file, per ridirigere l'output, l'input e l'error.

    Nell'esempio 2.3 dando il comando ls -l > dir.txt , la lista non viene visualizzata sul monitor, ma scritta sul file dir.txt.
    Usando "2> error.txt" si inviano i possibili messagi d'errore generati da un comando errato sul file error.txt.

    Vediamo qualche esempio, considerando che il comando:

    cat nomefile lista il contenuto del file (anche piu' di uno). Attenzione che sia un file di testo. Se il nomefile e' assente, il comando si aspetta un input da tastiera che termina con ctrD che rappresenta l'end of file.
    more nomefile lista il contenuto del file una pagina alla volta. Con la barra si visualizza una nuova pagina, con il taso p si torna indietro, con il return si va avanti di una rga, con il tasto q si chiude (quit).
    echo striga_di_caratteri scrive sul monitor la stringa data.

    ESEMPIO 2.6
    
    
    krypton > cat README
    ........ < listato del file README >
    
    krypton > cat > file2
    linea1                -->  scritti dall'utente
    linea2
    ^D   
    
    krypton > cat README file2 > file1
    
    krypton > alfa <file1 >file3 2>log
    
    

    Con il primo comando si lista su video il contenuto del file README.
    Con il secondo si crea il file file2, che conterra' le due righe scritte da tastiera dall'utente.
    Con il terzo i file README e file2 sono listati in sequenza sul file file1.
    Supponendo che "alfa" sia un programma utente che legge i dati dall'input e li scrive tali e quali sull'output, con il quarto comando si prende l'input da file1, che viene ricopiato su file3. Eventuali errori saranno scritti sul file log.

    Un altro carattere speciale riconosciuto e interpretato dalla shell e' la sequenza ">>": indica che l'ouptut va concatento ad un eventuale precedente contenuto.

    krypton > alfa <file1 >>file3 2>log
    
    Con quest'ultimo comando si fa un append del file file1 a file3. 

    I Pipe

    Problema: vogliamo sapere quanti processi attivi ci sono appartenenti all'utente gianuzzi.
    Il comando ps aux ci consente di conoscere tutti i processi (la lista potrebbe essere lunga).
    Il comando grep stringa_caratteri lista_file ci consente di cercare le occorrenze della stringa all'interno dei file indicati.

    I comandi

    krypton > ps aux > proc
    krypton > grep gianuzzi proc
      gianuzzi  5843 20,0  1,7 2,03M 520K ttyp4    S    14.42.18     0:01.48   - (tcsh)
      gianuzzi  4389  3,0  2,3 9,49M 696K ??       S    09.38.53     0:08.86   /usr/bin/X11/mwm
    
    krypton > rm proc
    

    mi consentono di fare quanto voglio, ma creando il file intermedio proc, che va poi cancellato.

    In Unix c'e' la Špossibilita' di definire un pipe (tubo) di comandi, in cui l'output di un comando e' usato come input del successivo.

    krypton > ps aux | grep gianuzzi
    
      gianuzzi  5843 20,0  1,7 2,03M 520K ttyp4    S    14.42.18     0:01.48   - (tcsh)
      gianuzzi  4389  3,0  2,3 9,49M 696K ??       S    09.38.53     0:08.86   /usr/bin/X11/mwm
    
    

    Il carattere "|" (che e' un altro dei caratteri gestiti dalla shell) separa due comandi: l'output del primo e' l'input del secondo. Si puo' fare una sequenza di piu' di due comandi.

    La stringa cercata da grep potrebbe anche essere espressa attraverso una espressione regolare.

    Espressioni regolari

    Quanto segue non e' una esposizione completa.
    Si puo' trovare la definizione completa della grammatica regolare utilizzata dalla shell consultandone il manuale in linea.

    Se l'argomento di un comando e' una lista di nomi descrivibile come espressione regolare sull'insieme dei caratteri, si possono indicare con caratteri particolari.

    "*" sta per qualsiasi numero (anche zero) di caratteri diversi da "/".
    "?" puo' essere sostituito da un singolo carattere.
    la stringa racchiusa fra doppi apici " e' presa cosi' com'e'.

    Il meccanismo usato dalla shell e':

    krypton > ls
    f1.c      f2.c       f3.txt        m.tex 
    
    krypton > ls *
    f1.c      f2.c       f3.txt        m.tex
    
    krypton > ls f*
    f1.c      f2.c       f3.txt
    
    krypton > ls *.c
    f1.c      f2.c  
    
    krypton > ls f*.?
    f1.c      f2.c
    

    Ci sono altre possibilita', ad esempio /usr/[a-f]* indica tutti i file della directory "/usr" il cui nome inizia con una lettera minuscola fra "a" e "f" comprese.

    Nella sezione 4 ( La shell bash) verra' spiegato il linguaggio accettato da questo tipo di shell.

    Comandi per lavorare su Rete ( Indice )

    Quanto segue e' solo un cenno sui comandi disponibili per lavorare su un host remoto. L'argomento sara' approfondito nella sezione sui sistemi distribuiti.

    I comandi qui sotto possono essere eseguiti solo se l'utente ha un account (login) sull'host remoto, e se sono state effettuate le necessarie modifiche ai file di sistema descritti sotto (gestiti dal sistemista).

    File utilizzati per connessione
    /etc/hosts
    Contiene l'elenco di indirizzi IP (Internet Protocol) e nomi host della rete locale.
    Ricordiamo che un host viene identificato da un nome simbolico, per comodita' dell'utente, e da un indirizzo numerico, nel nostro caso un indirizzo Internet, dai servizi di rete. Lo stesso indirizzo Internet puo' avere piu' di nome simbolico associato.

    Il nome simbolico di un host e' formato da due campi: il nome semplice dell'host (es.krypton) e quello della rete su cui si trova (es. disi.unige.it). Lo stesso vale per l'indirizzo IP ma in modo rovesciato: l'indirizzo dell'host e' l'ultimo valore (ad esempio 107 e' l'indizzo IP dell'host krypton, mentre 130.251.61 e' l'indirizzo della rete disi.unige.it).

    ESEMPIO 2.7
    130.251.61.105 xenon.disi.unige.it xenon
    127.0.0.1 localhost
    130.251.61.107 krypton.disi.unige.it krypton
    130.251.61.1 iris
    130.251.61.11 diana.disi.unige.it diana
    130.251.60.13 cartesio.dima.unige.it cartesio
    130.251.61.7 violet
    .....

    /etc/networks
    Contiene nomi e indirizzi IP della rete utilizzati per l'instradamento, per indicare cioe' una rete con il nome invece dell'indirizzo IP.

    /etc/resolv.conf
    Utilizzato per ottenere l'indirizzo IP che corrisponde ad un nome di host.
    Lista le coppie name-value che forniscono informazioni per il BIND resolver.

    Coppie:
    domain <domainname> local domain name
    nameserver <address> Internet address di un name server

    ESEMPIO 2.8

    nameserver 130.251.61.19; elios.disi.unige.it elios
    nameserver 130.251.60.13 ; perceval.dima.unige.it perceval
    
    

    /etc/hosts.equiv
    Contiene una lista di "trusted hosts". Usato dai comandi rsh, rlogin e rcp. Attenzione: gli host listati possono compromettere la security.
    Sono listati:

    Se non sono specificati user, tutti gli utenti sono abilitati.
    In pratica cio' consente ad un utente remoto listato in questo file di eseguire comandi sull'host senza necessita' di dare la password.

    1. Remote Login             rlogin host

    Consente di effettuare un login remoto sulla macchina host. Ovviamente occorre avere un account su quella macchina. Successivamente si potra' dare comandi che verranno inviati all'host remoto, e riceverne l'output.

    2. Remote Shell             rsh host command

    Esegue "command" sulla shell remota di "host".
    Per poter funzionare l'utente deve essere autorizzato a lavorare sull'host remoto senza necessita' di inserire password. Se ne riparlera' in una prossima sezione sui sistemi distribuiti. Si esce con il comenado exit.

    ESEMPIO
    krypton > rsh arsenio ps aux|grep gianuzzi

    esegue sulla macchina "arsenio" il comando "ps aux|grep gianuzzi", listando l'output sul terminale locale.
    Se non e' specificato nessun comando, viene in realta' eseguito il comando "rlogin" (remote login). I metacaratteri della shell non "quoted" sono interpretati relativamente all'host locale, mentre quelli "quoted" sono riferiti all'host remoto.

    ESEMPIO
    rsh other_host cat remote_file >> local_file
    rsh other_host cat remote_file ">>" other_remote_file

    Il primo comando fa un append del file remoto "remote_file" memorizzato su "other_host" dopo il file "local_file" sull'host locale.
    Il secondo comando fa un append del file remoto "remote_file" dopo il file remoto "other_remote_file" sull'host remoto.

    3. Funzione di esecuzione remota             rexec, rexec_r

    Consentono l'esecuzione di un comando su remote host.
    Si tratta di un comando piuttosto complesso, di cui e' riporata sotto la sintassi, ed e' inserito qui solo per completezza. Maggiori spiegazioni si trovano nella sezione Sistemi Distribuiti.

    SINTASSI 
    
          #include <netdb.h>
          int rexec(
                 char **host,
                 int port,
                 char *user,
                 char *passwd,
                 char *command,
                 int *err file desc);
          int rexec_r(
                 char **host,
                 int port,
                 char *user,
                 char *passwd,
                 char *command,
                 int *err file desc,
                 struct hostent_data *host data);
    

    PARAMETRI

    1. host nome e' l'host remoto (deve essere listato in /etc/hosts file o in /etc/resolv.conf).
    2. port specifica una well-known Internet port da usarsi per la connessione (tcp).
    3. user punta ad un user ID valido su quell'host.
    4. passwd punta alla password dell'utente specificato.
    5. command punta al nome del comando che deve essere eseguito in remoto.
    6. err file desc specifica il file a cui deve essere inviato lo standard error dal remote command. Ecc.
    7. host data ecc.

    Se rexec() connection ha successo, viene ritornato un socket del dominio Internet (SOCK STREAM) ed e' passato al al comando remoto come standard input e standard output. Se non sono forniti i parametri user e passwd, rexec() esegue le seguenti azioni finche' non trova uno user ID e password da inviare al remote host:

    Tutti i comandi sopra discussi sono presentati solo a grandi linee. Per maggiori e necessarie spiegazioni, consultare il manuale in linea.

    Libri consultabili

    Unix Network Programming (Stevens), Prentice-Hall, 1990.
    (esempi di programmi con connessioni TCP e UDP)

    Libri consultabili, soprattutto per chi vuole istallare un collegamento Internet a casa, altrimenti aspettare il corso di RETI!!!