Lezione Precedente Elenco Lezioni Lezione Successiva

Laboratorio di Sistemi Informativi

Introduzione a Linux

Come detto, questo non è un corso completo su Linux, per cui ci limiteremo ad illustrare soltanto alcuni aspetti del sistema operativo. Per avere maggiori informazioni, si possono consultare:

Tutte le lezioni sono pensate per la distribuzione Ubuntu 8.04, che è quella installata in aula informatizzata. Cambiando distribuzione, alcuni dettagli potrebbero essere differenti, in particolare per quanto concerne le interfacce grafiche. In generale, questo è il risultato di uno dei grandi vantaggi (e svantaggi) di Linux, ovvero l'estrema configurabilità: due macchine che eseguono Linux possono apparire completamente diverse l'una dall'altra. Il vantaggio è l'estrema adattabilità alle esigenze dell'utilizzatore, lo svantaggio è che l'utente inesperto si trova disorientato passando da un computer Linux a un altro.

L'utilizzo generale di Linux non è dissimile da quello di Windows, soprattutto nelle ultime versioni. Ovviamente non ci si può aspettare di trovare gli stessi programmi che si hanno su Windows, ma quasi sempre ce n'è di equivalenti. Non ci dilunghiamo quindi sul funzionamento generale ed andiamo ad analizzare le differenze maggiori tra i due sistemi.

L'albero delle directory

Per avere accesso a directory e file presenti nel computer, basta andare nel menù Places e selezionare una delle voci che in esso compaiono. Le più utili sono Home Folder, che conduce alla propria home directory, e Computer, che consente di esplorare tutti le unità di memoria presenti nel sistema. Ogni utente ha una home directory, che può gestirsi come vuole, e dove può salvare tutti i propri dati. Modifiche alla propria home directory non influenzano le home directory degli altri utenti.

Diamo ora una occhiata rapida all'albero delle directory completo di un sistema Linux. A differenza di Windows, che è strutturato in modo da avere (più o meno) una directory per ogni programma, in Linux la struttura del file-system è molto più articolata. Per iniziarne l'esplorazione, basta selezionare in sequenza i menù Places e Computer e poi fare doppio click su Filesystem Nel resto della lezione, scriveremo una tale sequenza di comandi nella forma Places → Computer → Filesystem.

/
+--- bin
+--- boot
+--- etc
+--- home
     +--- amato
          +--- Desktop
    +--- LABECONOMIA
          +--- gamato
               + Desktop
+--- lib
+--- media
     +--- cdrom
     +--- floppy
+--- proc
+--- root
+--- sbin
+--- sys
+--- tmp
+--- usr
     +--- bin
     +--- lib
+--- var

Abbiamo qui indicato solo le directory più importanti. Spieghiamo brevemente la loro funzione:

Attenzione. Ricordate che quando trovate scritta una cosa del tipo <nomeutente>, non vuol dire che bisogna digitare la stringa nomeutente tra i simboli di minore e maggiore (chiamati anche parentesi angolari), ma che al posto di <nomeutente> va sostituito il nome di un utente specifico. Così, /home/<nomeutente> va digitato in realtà come /home/amato, /home/rossi o simili.

Normalmente un utente (che non sia root) può leggere quasi tutti i file presenti nel computer, ma può scrivere soltanto nella sua home directory e nella directory /tmp.

La shell

Nei sistemi Unix, la shell è il programma più importante, dopo il sistema operativo vero e proprio (detto di solito kernel). È il mezzo con cui si comunica con il sistema e attraverso il quale si avvia e si controlla l'esecuzione degli altri programmi. Shell vuol dire "conchiglia" e il nome deriva dal fatto che è la superficie con cui l'utente entra in contatto quando vuole interagire con il sistema: la shell racchiude il kernel.

Una volta, prima dell'avvento delle interfacce grafiche, la shell era l'unico mezzo per comunicare con il sistema operativo. Oggi non è più così, ma la shell, per chi la sa usare, conserva ancora dei vantaggi rispetto all'interfaccia grafica:

La shell è disponibile anche per sistemi Windows, anche se lì si chiama, per motivi storici "prompt dell'MS-DOS" o "prompt dei comandi". Tuttavia, essa è molto meno potente che nei sistemi Unix, per cui è di solito meno utilizzata.

In realtà in Unix esistono varie shell dei comandi, ma le due più utilizzate sono sicuramente la bash e la tcsh, che hanno ovuto origine nei sistemi Unix System V e BSD rispettivamente. Noi studieremo la bash perché è quella standard di Linux.

Il prompt dei comandi

Per avviare la shell, basta selezionare Applications → Accessories → Terminal. Appare una finestra simile a questa:

screenshot di una finestra terminale

La scritta "amato@sci138:~$" è il prompt dei comandi: indica che la shell è attiva e pronta ad accettare richieste dall'utente. Riconosciamo le seguenti componenti nel prompt:

Attenzione. È possibile modificare il prompt rispetto a quello di default... per cui non fate troppo affidamento su questa descrizione.

Dal prompt è possibile digitare i comandi che si vogliano inviare al sistema, utilizzando anche i tasti standard per l'editing: Canc, Backspace, Inizio, Fine, Freccia sx, Freccia dx. I tasti Freccia su e giù consentono invece di scorrere i comandi già immessi precedentemente, che possono poi essere modificati.

Alcuni comandi

Dalla shell è possibile inviare dei comandi al sistema operativo. Ecco alcuni esempi:

La struttura generale di un comando è

<nomeprogramma> <lista di argomenti>

Tipicamente un comando della shell non è altro che il nome di un programma che il sistema operativo deve eseguire: ls, cat, cp, mv sono tutti programmi, e abbiamo visto che risiedono nelle directory /bin, /sbin, /usr/bin e simili. Ma anche programmi più "corposi" possono essere eseguiti semplicemente digitandone il nome dalla shell. Non vi ricordate più in che menù sta nascosto il programma d'ufficio OpenOffice? Basta dare il comando openoffice e questo partirà regolarmente.

Percorsi assoluti e relativi

Abbiamo visto che molti comandi hanno come argomento un nome di file. Ma che struttura ha un nome di file Linux? Nel vecchio sistema operativo DOS, il nome aveva una struttura fissa di 8 caratteri, un punto, e altri 3 caratteri (detti estensione). L'estensione serviva a identificare il tipo di file: .jpg per file immagini JPEG, .txt per file di testo puri, .doc per file Word, etc..

Su Linux (e per buona parte anche in Windows), un nome di file è una stringa di caratteri qualunque, e può contenere quanti punti si desidera (anche nessuno). L'estensione non è necessaria, ma spesso la si aggiunge per facilitare la vita all'utilizzatore del computer, che così è in grado di riconoscere il tipo di ogni file. Anche alcuni programmi si basano sull'estensione di un file per decidere come trattarlo. Notare che, su Linux, l'estensione può anche essere più lunga di 3 caratteri: ad esempio .html è l'estensione standard per i file HTML.

Tuttavia, specificare semplicemente il nome di un file non è sufficiente. Infatti, all'interno del file system possono esserci molti file con lo stesso nome, ma che stanno in directory diverse. Come si fa, allora, a indicare con esattezza un file specifico, in modo che non sorgano ambiguità? Bisogna utilizzare i pathname (nomi dei percorsi) che possono essere di due tipi: assoluti o relativi.

Un percorso assoluto è una stringa del tipo:

/<nomedir>/<nomedir>/<nomedir>/<nomefile>

che inizia con la barra di divisione, ha una serie di componenti separati da barre e termina con un nome di file. La sequenza dei vari <nomedir> è la sequenza di directory dentro le quali il sistema deve entrare, partendo dalla radice, per raggiungere la directory dove si trova il <nomefile> desiderato. Ad esempio:

Sono importanti alcune cose:

Ogni processo (programma in esecuzione) in Linux ha una directory corrente.  Quando si specifica un nome di file direttamente, senza percorso, il file viene cercato in questa directory. Per cambiare directory corrente nella shell di Linux, si può usare il comando cd (change dir). Più in generale, la directory corrente serve come punto di riferimento per i percorsi relativi.

Un percorso relativo è una stringa di questo tipo:

<nomedir>/<nomedir>/<nomedir>/<nomefile>

quindi è simile a un percorso assoluto ma non ha la barra iniziale. Anche il significato è simile a quello di un percorso assoluto, con la differenza che la directory da cui iniziare la ricerca del file non è la directory radice ma la directory corrente. Nei percorsi relativi si una spesso una directory speciale, la directory .. (due punti), che indica la directory padre di quella corrente, consentendo quindi di risalire l'albero delle directory. Ad esempio, se la directory corrente è /home,  allora:

Di solito ovunque si può inserire il nome di un file, si può inserire un percorso assoluto o relativo. Ma quale conviene usare tra i due? Quando si usa la shell in maniera interattiva, come facciamo noi in questa lezione, si può usare quello che ci torna più comodo. Quando però si scrivono dei programmi che hanno bisogno di accedere a vari file ad essi correlati, è meglio utilizzare percorsi relativi. In questo modo, sarà poi più facile spostare tutto il software da una directory ad un altra senza comprometterne il funzionamento.

Ad esempio, supponiamo di aver scritto un programma vis che ha bisogno di alcune immagini per funzionare. Decidiamo di mettere il programma vis nella directory /home/amato/prg e le immagini in una sottodirectory, ad esempio /home/amato/prg/img. Quando nel programma abbiamo bisogno di riferirci ad una immagine, è meglio se usiamo un percorso relativo alla directory /home/amato/prg. Così, l'immagine titolo.jpg dovrà essere riferita con il percorso titolo.jpg. In questo modo, quando ci porteremo il programma a casa nel nostro computer, potremo decidere di mettere il tutto (il programma vis e la sottodirectory img) nella directory /usr/local/mioprog e il programma continuerà a funzionare a dovere. La vecchia immagine /home/amato/prg/img/titolo.jpg non esiste più, ma al suo posto abbiamo /usr/local/mioprog/titolo.jpg e, partendo da /usr/local/mioprog il percorso relativo img/titolo.jpg  punta propro a quest'ultima.

Comandi e opzioni

A molti dei comandi visti finora è possibile aggiungere delle opzioni per alterarne il  funzionamento. Ad esempio, ls può prendere come argomento i seguenti parametri (e tanti altri che qui non cito):

Quelle che abbiamo visto qua sopra sono le "opzioni corte". Esse hanno tutte la stessa forma: il segno - seguito da una lettera. Alcuni programmi supportano anche delle opzioni lunghe. Ad esempio per ls abbiamo:

Le opzioni possono essere combinate tra di loro. Ad esempio 'ls -a -l' visualizza tutti i file, compresi quelli nascosti, e visualizza per ognuno i suoi attributi. Stesso risultato da 'ls --all -l'. Un altro modo di combiare le opzioni corte è usare un unico simbolo - e, in sequenza, le lettere corrispondenti alle varie opzioni. Ad esempio 'ls -al' ha lo stesso effetto di 'ls -a -l'.

Nota. Le opzioni --help e --version sono comuni a molti programmi. Se non si sa cosa fa il programma chown, il comando chown --help è un buon modo per scoprirlo.

Completamento automatico

Una caratteristica utile della shell di Linux è il completamente automatico. In varie circostante potete premere il tasto <TAB> e la shell completa quello che state scrivendo nella maniera più ovvia. Il tasto <TAB> (tabulazione) si trova quasi sempre a sinistra, sotto la barra retroversa (\), e su di esso sono disegnate due frecce puntate in direzioni opposte. Ad esempio, se siete nella situazione

amato@sci138$ pass

e premete <TAB>, la stringa pass viene completata in passwd (il comando per cambiare la propria password). Questo perché passwd è l'unico comando che inizia con pass.  Analogamente, se nella directory corrente c'è il file "prova" e voi premete <TAB> quando avete digitato

amato@sci138$ cat pr

allora pr viene completato in prova. In generale, quasi su ogni sistema è vero quanto segue:

Talvolta premendo <TAB> non succede niente: vuol dire che c'è ambiguità nel modo in cui si può completare la stringa. Ad esempio, se abbiamo anche il file prato oltre a prova, premere <TAB> dopo pr è ambiguo perché pr potrebbe essere completato con prato o con prova.

In questo caso, si può premere <TAB> due volte di seguito per avere l'elenco dei possibili completamenti. Ad esempio, con

amato@sci138$ rm

premendo <TAB><TAB> si ha l'elenco dei comandi che iniziano con rm:

rm              rmail.sendmail  rmic            rmiregistry
rmail           rmdir           rmid

Il <TAB> può essere usato per spostarsi velocemente nell'albero delle directory. Se si vuole visualizzare il file /etc/network/interfaces (che contiene la configurazione per la scheda di rete) il comando da dare è cat /etc/network/interfaces. Si può scrivere questo comando molto più velocemente digitando: cat /e<TAB>ne<TAB>/in<TAB>. Se invece volete visualizzare un file in /etc/network ma non vi ricordate quale, potete provare con cat /etc/network/<TAB><TAB><TAB> che visualizza l'elenco dei file in /etc/network

La funzione di completamento automatico è veramente comoda. Una volta che ci si è famirializzato, è difficile farne a meno.

Attenzione. Questo che abbiamo appena visto è un altro tipico utilizzo delle parentesi angolari. Quando l'oggetto tra i simboli di minore e maggiore è il nome di un tasto, come nel caso di <TAB>, vuol dire che bisogna premere il tasto corrispondente sulla tastiera. Questo è un po' in contrasto con quanto visto precedentemente sull'uso delle parentesi angolari, ma di solito non ci dovrebbero essere ambiguità sul loro significato.

Immissione caratteri speciali

Spesso è necessario inserire dei caratteri che non sono presenti nella tastiera. Come si fa in questo caso? Il trucco tipico di Windows (<Alt>+il codice ascii sul tastierino numerico) su Linux non funziona. In realtà, i caratteri più comuni possono essere digitati con alcune combinazioni di tasti standard:

Per chi non lo sapesse, il tasto <AltGr> è il tasto <Alt> posto a destra della barra spaziatrice.

Aiuto, non mi ricordo cosa fa un comando

Nessuno è ingrado di ricordarsi tutti i possibili comandi e le differenti opzioni disponibili in ambiente Unix. Per fortuna la documentazione in materia è estensiva. Abbiamo già visto l'opzione --help che è possibile fornire a molti comandi per farci restituire la spiegazione del suo funzionamento e delle opzioni che supporta. La spiegazione che si ottiene è però spesso troppo stringata, utile quando il comando lo si conosce già e semplicemente non ci si ricorda il formato di qualche opzione, ma non quando si vuole imparare come utilizzarlo.

Per quest'ultimo scopo è molto più utile il comando man. Si usa generalmente in questo modo:

Ad esempio man rmdir visualizza il manuale del comando rmdir.

La lettura del manuale non è sempre agevole e bisogna abituarsi un po', anche perché spesso le spiegazioni sono molto tecniche. Le due parti più importanti sono tipicamente SYNOPSIS che dà la sintassi del comando e DESCRIPTION che spiega cosa fa il comando e il significato di tutte le opzioni disponibili.

File, utenti, diritti

Unix è un sistema operativo multi-utente. Vuol dire che più persone possono utilizzare il computer, anche contemporaneamente, e il sistema deve garantire un certo livello di sicurezza: impedire, ad esempio, che i file privati di un utente possano essere letti da un altro senza autorizzazione.

Noi descriveremo il sistema di gestione dei diritti standard di Linux. Ultimamente ci sono stati vari sviluppi per aumentare ulteriormente la sicurezza e la protezione del sistema: tra questi SELinux (Security Ehanced Linux) che è presente di default in alcune distribuzioni (ad esempio nella Fedora) ma non nella Ubuntu.

Utenti e gruppi

Due sono i concetti principali per tutte le politiche di sicurezza: l'utente e il gruppo. Quando si effettua il login, bisogna specificare la username con cui ci si collega e la password relativa. Un elenco di tutti gli utenti del sistema si può trovare, di solito, nel file /etc/passwd (che non commenteremo oltre), mentre un elenco dei gruppi si trova in /etc/group. Per sapere l'utente, il gruppo corrente e i gruppi a cui appartiene, basta dare il comando:

Ad esempio, il risultato di id potrebbe essere:
uid=1000(amato) gid=1000(amato) gruppi=24(cdrom),25(floppy),29(audio),1000(amato)
dove i vari campi hanno il seguente significato:

Il gruppo corrente (gid) determina il gruppo con cui viene creato un nuovo file, mentre l'elenco dei gruppi determina i diritti di accesso dell'utente.

File e diritti

È possibile specificare i diritti di accesso degli utenti ai file in base ai due concetti di utente e di gruppo. Ogni file presente sul sistema appartiene ad un utente e a un gruppo ben specifico: si chiamano i proprietari del file.

Le operazioni che è possibile compiere su un file si possono dividere in  3 grossi gruppi:

Ognuna di queste operazioni può essere concessa o negata a tre diversi tipi di utente:

È così possibile specificare che il file pippo.sh può essere letto e scritto dal suo proprietario, solo letto da un altro utente del suo gruppo, e completamente inaccessibile a un'altra persona.

Ma come si fa a sapere chi è il proprietario di un file e quali sono i permessi di accesso? Dalla interfaccia grafica basta cliccare col tasto destro sul file che ci interessa e selezionare Properties dal menù contestuale che viene fuori. Selezionando la cartellina Permissions si otterrano tutte le informazioni volute e sarà anche possibile modificarle.

Finestra con i permessi di accesso ad un file

Per quanto riguarda la linea di comando, per vedere i permessi di un file è possibile usare il comando ls con l'opzione -l. Per ogni file compare, sul lato sinistro, una stringa del tipo "-rwxrwxrwx". Il primo carattere contiene informazioni sul tipo di file (è - per un file normale e d per una directory). I caratteri successivi vanno letti a blocchi di 3, e contengono l'informazione sui diritti per il proprietario, il gruppo, e gli altri utenti rispettivamente. Se il carattere r, w o x compare vuol dire che i diritti relativi sono stati concessi, se al suo posto compare - allora sono stati negati. Ad esempio la stringa "-rwxrw-r--" indica un file che può essere manipolato come si vuole dal suo proprietario, letto ed eseguito dal suo gruppo e solo letto dagli altri utenti. È anche possibile modificare i permessi dalla shell con il comando chmod, ma la sintassi è un po' complessa, per cui lascio agli interessati scroprire come.

Risultato di ls con l'opzione -a

I diritti di lettura, scrittura ed esecuzione si possono concedere anche a delle directory. Ma mentre sembra chiaro cosa vuol dire lettura e scrittura per una directory, cosa vuol dire "esecuzione" in questo caso?

Avere il diritto di esecuzione su una directory vuol dire essere in grado di entrare in una directory.  È possibile anche accedere ai file che stanno in quella directory, purché se ne conosca il nome!! Tuttavia il diritto di esecuzione non ci consente di esaminare il contenuto di una directory con ls. Quest'ultima operazione è possibile solo se sulla directory abbiamo il diritto di lettura.

Diventare super-utenti

Abbiamo già detto che tra tutti gli utenti ce n'è uno particolare, denominato root, che ha il ruolo di super-utente. A lui non si applicano le normali restrizioni di accesso che hanno gli altri utenti, ma può accedere a tutti i file presenti sul sistema.

Sulla Ubuntu non è possibile fare il login direttamente come super-utente: bisogna prima fare il login come utente normale e poi, se si è abilitati, si può diventare super-utenti. Per far ciò, bisogna dare dalla shell il comando:

Il sistema potrebbe chiedere la propria password e, se tutto va bene, vi fa diventare root (la nuova identità è riconoscibile dal fatto che il prompt della shell termina con un #). A quel punto, qualunque comando inserito da quella shell verrà eseguito con i diritti di root.

Se invece volete dare un solo comando come super utente, per poi tornare ad operare come un utente normale, si può usare il comando:

Anche in questo caso il sistema potrebbe chiedere di reimmettere la password.

Installazione di programmi

Se il software che vogliamo installare fa parte della distribuzione standard di Ubuntu, possiamo installarlo scegliendo Applications → Add/Remove... dai menù del desktop. Il programma che viene avviato ha una interfaccia molto semplice, ma purtroppo tramite esso è possibile installare solo un numero limitato di applicazioni.

Il programma base per la installazione di nuove applicazioni

Per un controllo totale sul software installato, invece, si può usare il programma Synaptic, che trovate nel menù System → Administration → Synaptic Package Manager. Si noti che per utilizzare Synaptic (o per installare del software tramite l'interfaccia semplificata di cui sopra) è necessario che l'utente sia autorizzato ad agire come amministratore, ed occorre inserire per sicurezza la propria password qualora essa venga richiesta.

Synaptic Package Manager

Nel caso in cui il software cercato non faccia parte della distribuzione standard, occorrerà procurarselo in qualche modo, tipicamente scaricandolo da Internet. Esistono vari modi e formati in cui il software può essere distribuito, ma per la Ubuntu il formato più comodo è il deb. Un file in formato deb (chiamato pacchetto) è un file compresso (simile a un file ZIP) che contiene delle informazioni speciali per l'installazione e disinstallazione del software. Per installare un pacchetto deb basta fare un doppio-click su di esso. Anche per questa operazione, ovviamente, bisognerà godere dei diritti di amministratore. Il programma installato in questo modo lo si può poi rimuovere normalmente utilizzando Synaptic.

Installazione software necessario per il corso

Al software che viene automaticamente installato con il sistema operativo, bisogna aggiungere anche una serie di pacchetti per MySQL e PHP. Utilizzando Synaptic Package Manager, installare i pacchetti: mysql-server, mysql-client, php5, php5-mysql. Durante l'installazione viene chiesto di inserire una password che sarà poi utilizzata per accedere a MySQL come utente root: vedremo dopo cosa vuol dire, per ora basti sapere che è necessario inserire una password a piacimento e annotarla da qualche parte, perché servirà per la prossima lezione. Tenete conto che per installare questi pacchetti è necessario essere collegati ad Internet, o avere a disposizione un DVD (non un CD) di Ubuntu.

Esercizi e Soluzioni

Esercizio 1

Visualizzare il contenuto del file /proc/cpuinfo.

Esercizio 2

Esaminare l'elenco delle periferiche PCI presenti nel sistema eseguendo il programma /usr/bin/lspci.

Esercizio 3

Utilizzando i comandi della shell, creare all'interno della vostra home directory una cartella dal nome prova e, dentro quest'ultima, una ulteriore cartella dal nome prova-nidificata. Creare dentro prova-nidificata un file di testo di nome provatesto.txt con un contenuto a piacere (come editor di testi si può usare gedit).  Controllare che il contenuto sia leggibile usando il comando cat. A questo punto spostare il file provatesto.txt nella directory prova con il nuovo nome provatesto2.txt, e cancellare la directory prova-nidificata.

Esercizio 4

Creare la directory prova-nidificata2 dentro la directory prova e prova-nidificata3 dentro prova-nidificata2. Creare un file di testo prova-file dentro prova-nidificata3 con un contenuto a piacere.  Il metodo standard che abbiamo visto per cancellare una directory dalla shell è quello di cancellare prima i file che essa contiene con rm e poi la cartella stessa con rmdir. Senza seguire questa procedura, consultare la documentazione sul comando rm e capire come cancellare, con un unico comando, la directory prova e tutte le sue sottodirectory.

Lezione Precedente Elenco Lezioni Lezione Successiva

Valid HTML 4.01 Transitional Valid CSS!