Capitolo successivo Capitolo precedente Indice

2. Introduzione a Linux

Linux, come sistema operativo, è il risultato di una serie molto grande di apporti da diversi ambienti Unix. Quindi, gran parte di ciò che riguarda o compone Linux, non è esclusivo di questo ambiente.

Questo capitolo introduttivo è rivolto a tutti i lettori che non hanno avuto esperienze con Unix, ma anche chi ha già una conoscenza di Unix farebbe bene a darci un'occhiata.

2.1 Case sensitive

I sistemi operativi Unix, e quindi anche Linux, sono sensibili alla differenza tra le lettere maiuscole e minuscole. La differenza è sostanziale, per cui gli ipotetici file denominati: Ciao, cIao, CIAO, ecc. sono tutti diversi.

Non bisogna confondere questa caratteristica con quello che può succedere in altri ambienti, come per esempio MS-Windows95, che preservano l'indicazione delle lettere maiuscole o minuscole, ma che poi non fanno differenza quando si vuole fare riferimento a quei file.

2.2 Utenti

Linux, come gli altri sistemi derivati da Unix, è multiutente. La multiutenza implica una distinzione tra i vari utenti. Fondamentalmente si distingue tra l'amministratore del sistema, o superuser, e gli altri utenti.

L'amministratore del sistema è quell'utente che può fare tutto quello che vuole, soprattutto rischia di produrre gravi danni anche solo per piccole disattenzioni.

L'utente normale è quello che utilizza il sistema senza pretendere di organizzarlo e non gli è possibile avviare programmi o accedere a dati che non lo riguardano.

Account

Per poter utilizzare un sistema di questo tipo, occorre essere stati registrati, ovvero, occorre avere ottenuto un account.

Dal punto di vista dell'utente, l'account è un nome e una password che gli permettono di essere riconosciuto e quindi di poter accedere. Oltre a questo, l'account stabilisce l'appartenenza ad un gruppo di utenti.

Il nome dell'amministratore è sempre root, quello degli altri utenti viene deciso di volta in volta.

Account e monoutenza

I sistemi Unix e i programmi che su questi sistemi possono essere utilizzati, non sono predisposti per un utilizzo distratto: gli ordini non vengono discussi. Molti piccoli errori possono essere disastrosi se sono compiuti dall'utente root.

È molto importante evitare il più possibile l'utilizzo dell'account dell'amministratore anche quando si è l'unico utilizzatore del proprio computer.

2.3 Composizione

Il sistema operativo Linux, così come tutti i sistemi operativi Unix, è composto essenzialmente da:

Boot

Il boot è il modo con cui un sistema operativo può essere avviato quando il computer viene acceso. Di solito, il software registrato su ROM dei computer basati sull'uso di dischi, è fatto in modo da eseguire le istruzioni contenute nel primo settore di un dischetto, oppure, in sua mancanza, del cosiddetto MBR, o Master Boot Record che è il primo settore del primo disco fisso. Il codice contenuto nel settore di avvio di un dischetto o del disco fisso, provvede alla esecuzione del kernel (lo avvia).

Con Linux, la configurazione e la gestione del sistema di avvio, viene fatta attraverso due modi possibili:

Kernel

Il kernel, come suggerisce il nome, è il nocciolo del sistema operativo. I programmi utilizzano il kernel per le loro attività, e in questa maniera sono sollevati dall'agire direttamente con la CPU. Di solito, è costituito da un unico file il cui nome potrebbe essere vmlinuz (oppure zImage, zbImage e altri), ma può comprendere anche moduli aggiuntivi, per la gestione di componenti hardware specifici che devono poter essere attivati e disattivati durante il funzionamento del sistema.

Quando il kernel viene avviato (attraverso il sistema di avvio), esegue una serie di controlli diagnostici in base ai tipi di dispositivi (componenti hardware, chiamati anche periferiche) per il quale è stato predisposto, quindi esegue il mount del filesystem principale (root), e infine avvia la procedura di inizializzazione del sistema (init).

Filesystem

Il filesystem è il modo con cui sono organizzati i dati all'interno di un disco o di una sua partizione. Nei sistemi operativi Unix non esiste la possibilità di distinguere tra una unità di memorizzazione ed un altra, come avviene nel Dos, in cui ogni disco o partizione sono contrassegnati da una lettera dell'alfabeto (A:, B:, C:). Nei sistemi Unix, tutti i filesystem cui si vuole poter accedere, devono essere concatenati assieme in modo da formare un unico filesystem globale.

Quando un sistema Unix viene avviato, si attiva il filesystem principale, o root, e quindi possono essere collegati a questo altri filesystem a partire da una directory o sottodirectory di quella principale. Dal momento che per accedere ai dati di un filesystem diverso da quello principale occorre che questo sia collegato, nello stesso modo, per poter rimuovere l'unità di memorizzazione contenente questo filesystem, occorre interrompere questo collegamento. Ciò significa, che nei sistemi Unix non si può inserire un dischetto, accedervi immediatamente e toglierlo quando si vuole. Occorre dire al sistema di collegare il filesystem del dischetto, quindi lo si può usare come parte dell'unico filesystem globale. Al termine si deve interrompere questo collegamento e solo allora si può rimuovere il dischetto.


Collegamento di un filesystem secondario in corrispondenza di un mount point.

L'operazione con cui si collega un filesystem secondario nel filesystem globale, viene detta mount e normalmente si utilizza il verbo ``montare'' con questo significato; l'operazione inversa viene detta unmount e conseguentemente si utilizza il verbo ``smontare''. La directory a partire dalla quale si inserisce un altro filesystem è il mount point.

Inizializzazione e gestione dei processi

Linux, come tutti i sistemi Unix, è multitasking, cioè in grado di eseguire diversi programmi, o processi, contemporaneamente. Per poter realizzare questo, esiste un gestore dei processi elaborativi: init, che viene avviato subito dopo l'attivazione del filesystem principale, e a sua volta si occupa di eseguire la procedura di inizializzazione del sistema. In pratica, esegue una serie di istruzioni necessarie alla corretta configurazione del particolare sistema che si sta avviando.

Daemon

Molti servizi sono svolti da programmi che vengono avviati durante la fase di inizializzazione del sistema e quindi compiono silenziosamente la loro attività. Questi programmi sono detti daemon e questo termine va considerato come equivalente a server o ``esperto''.

Gestione dei servizi di rete

Nei sistemi Unix la gestione della rete è un elemento essenziale e normalmente presente. I servizi di rete vengono svolti da una serie di daemon attivati in fase di inizializzazione del sistema. Nei sistemi Linux, i servizi di rete sono controllati fondamentalmente da tre daemon:

Un servizio molto importante nelle reti locali consente di condividere porzioni di filesystem da e verso altri computer connessi. Questo si ottiene con il protocollo NFS che permette quindi di realizzare dei filesystem di rete.

Gestione della stampa

Tutti i sistemi operativi multitasking hanno un sistema di coda di stampa (spool). Linux utilizza normalmente il daemon lpd che in particolare è anche in grado di ricevere richieste di stampa remote e di inviare richieste di stampa a computer remoti.

Registrazione e controllo degli accessi

I sistemi Unix, oltre che multitasking, sono anche multiutente, cioè possono essere usati da più utenti contemporaneamente. La multiutenza dei sistemi Unix è da considerare nel modo più ampio possibile, nel senso che si può accedere all'utilizzo del computer attraverso la console, terminali locali connessi attraverso porte seriali, terminali locali connessi attraverso una rete locale e terminali remoti connessi attraverso il modem.

In queste condizioni, il controllo dell'utilizzazione del sistema è essenziale. Per questo, ogni utente che accede deve essere stato precedentemente registrato, con un nome e una ``parola di accesso'', o password.

La fase attraverso cui un utente viene riconosciuto e quindi gli viene consentito di agire, è detta login. Così, la conclusione dell'attività da parte di un utente è detta logout.

Shell - interprete dei comandi

Ciò che permette a un utente di interagire con un sistema operativo è la shell, che si occupa di interpretare e eseguire i comandi dati dall'utente.

Dal punto di vista pratico, il funzionamento di un sistema Unix dipende molto dalla shell utilizzata, di conseguenza, la scelta della shell è molto importante. La shell standard di Linux è bash.

Una shell Unix normale svolge i compiti seguenti:

Utility per la gestione del sistema

I comandi interni di una shell non bastano per svolgere tutte le attività di amministrazione del sistema. I programmi di utilità sono quelli che di solito hanno piccole dimensioni, sono destinati a scopi specifici di amministrazione del sistema o anche solo di uso comune.

Le utility di uso comune sono solitamente contenute all'interno delle directory /bin e /usr/bin. Quelle riservate all'uso da parte dell'amministratore del sistema, l'utente root, sono normalmente contenute in /sbin e /usr/sbin dove la lettera s iniziale, sta per superuser, con un chiaro riferimento all'amministratore.

Strumenti di sviluppo software

Tutti i sistemi operativi devono avere un mezzo per produrre del software. In particolare, Un sistema operativo Unix deve essere in grado di compilare programmi scritti in linguaggio C/C++. Gli strumenti di sviluppo di Linux, composti da un compilatore in linguaggio C/C++ e da altri programmi di contorno, sono indispensabili per poter installare del software distribuito in forma sorgente non compilata.

2.4 Spegnimento

Qualunque sistema operativo multitasking, e tanto più se anche multiutente, deve prevedere una procedura di spegnimento che si occupi di chiudere tutte le attività in corso prima di consentire lo spegnimento fisico del computer.

Linux permette solo all'utente root di avviare la procedura di spegnimento con il comando seguente.

# shutdown -h now

In teoria è possibile utilizzare la combinazione [Ctrl+Alt+Canc] per riavviare il sistema, ma è sempre preferibile eseguire uno shutdown per il riavvio del sistema.

# shutdown -r now

2.5 Dispositivi

I vari componenti hardware di un computer, sono rappresentati in un sistema Unix come file di dispositivo, normalmente contenuti nella directory /dev (device). Quando si vuole accedere direttamente a un dispositivo, lo si fa quindi utilizzando il nome del file di dispositivo corrispondente.

Tipi

Esistono due categorie fondamentali di dispositivi:

Il tipico dispositivo a caratteri è la console o la porta seriale, mentre il tipico dispositivo a blocchi è una unità disco. La tabella (seguente) mostra l'elenco di alcuni nomi di dispositivo di Linux.


dispositivo descrizione
/dev/fd0 la prima unità a dischetti
/dev/fd0H1440 unità a dischetti con l'indicazione esplicita del formato: 1440KB
/dev/hda il primo disco fisso IDE/EIDE
/dev/hda1 la prima partizione del primo disco fisso IDE/EIDE
/dev/hdb il secondo disco fisso IDE/EIDE
/dev/sda il primo disco SCSI
/dev/sda1 la prima partizione del primo disco SCSI
/dev/lp0 la prima porta parallela dal punto di vista di Linux
/dev/lp1 la seconda porta parallela dal punto di vista di Linux
/dev/cua0 la prima porta seriale (chiamate in uscita)
/dev/ttyS0 la prima porta seriale (chiamate in ingresso)
Alcuni nomi di dispositivo utilizzati da Linux.

Alcuni file di dispositivo, non fanno riferimento a componenti hardware veri e propri. Il più noto di questi è /dev/null utilizzato come fonte per il ``nulla'' o come pattumiera senza fondo.

Dischi

Le unità di memorizzazione a dischi sono dispositivi come gli altri, ma possono essere trattati in due modi diversi a seconda delle circostanze: i dischi, o le partizioni, possono essere visti come dei file enormi o come contenitori di file (filesystem).

Questa distinzione è importante perché capita spesso di utilizzare dischetti che non hanno alcuna struttura di dati essendo stati usati come se si trattasse di un unico file. Il caso più comune è dato dai dischetti di avvio contenenti solo il kernel: non si tratta di dischetti all'interno dei quali è stato copiato il file del kernel, ma si tratta di dischetti che sono il kernel.

È anche possibile avere dischetti di avvio organizzati normalmente con un filesystem, ma questo particolare tipo di dischetti di avvio viene descritto più avanti.

La visione che normalmente si ha delle unità di memorizzazione contenenti file e directory è una astrazione gestita automaticamente dal sistema operativo. Questa astrazione si chiama filesystem.

2.6 Organizzazione di un filesystem Unix

Tutto ciò che è contenuto in un filesystem Unix, è in forma di file: anche una directory è un file.

Regular file

Quando si vuole fare riferimento a un file nel senso stretto del termine, ovvero un archivio di dati, se si vuole evitare qualunque ambiguità si utilizza il termine regular file, o file normale.

Directory

Una directory è un file speciale contenente riferimenti ad altri file.

I dati contenuti in un filesystem sono organizzati in forma gerarchica schematizzabile attraverso un grafo orientato (albero) che parte da una radice e si sviluppa in rami e nodi. La figura (seguente) mostra uno schema semplificato di un grafo orientato.


Schema semplificato di un grafo orientato.

La radice è il nodo principale di questo grafo orientato, i rami rappresentano il collegamento (la discendenza) dei nodi successivi con quello di origine (il genitore). La radice corrisponde a una directory, mentre i nodi successivi possono essere directory, file di dati o file di altro genere.

Per identificare un nodo (file o directory), all'interno di questa gerarchia, si definisce il percorso (path). Il percorso è espresso da una sequenza di nomi di nodi che devono essere attraversati, separati da una barra obliqua (/). Il percorso pluto/pippo/topolino rappresenta un attraversamento dei nodi pluto, pippo e topolino.

Dal momento che il grafo di un sistema del genere ha un nodo di origine corrispondente alla radice, si distinguono due tipi di percorsi: relativo e assoluto.

Il nodo della radice non ha un nome come gli altri: viene rappresentato con una sola barra obliqua (/), di conseguenza, un percorso che inizia con tale simbolo, è un percorso assoluto. Per esempio, /paperone/paperino indica un percorso assoluto che parte dalla radice per poi attraversare paperone e quindi raggiungere paperino.

Il grafo di un filesystem normale è orientato, nel senso che ha una direzione, ovvero ogni nodo ha un genitore e può avere dei discendenti e il nodo radice rappresenta l'origine. Quando in un percorso si vuole tornare indietro verso il nodo genitore, non si usa il nome di questo, ma un simbolo speciale rappresentato da due punti in sequenza (..). Per esempio, ../topolino rappresenta un percorso relativo in cui si raggiunge il nodo finale, topolino, passando prima per il nodo genitore della posizione corrente.

In alcuni casi, per evitare equivoci, può essere utile poter identificare il nodo della posizione corrente. Il simbolo utilizzato è un singolo punto (.). Per cui, il percorso pluto/pippo/topolino è esattamente uguale a ./pluto/pippo/topolino.

Link

Un grafo orientato, ovvero un albero, è tale quando esiste un solo percorso per unire due nodi di questo. Nei filesystem Unix non è necessariamente così. È infatti possibile inserire dei collegamenti, o link, aggiuntivi per permettere l'utilizzo di percorsi alternativi. Si distinguono due tipi di link: simbolici e hard.

In generale si preferisce l'uso di link simbolici per poter distinguere la realtà (o meglio l'origine) dalla finzione. Utilizzando un link simbolico si dichiara apertamente che si sta indicando una scorciatoia e non si perde di vista il percorso originale.

In questo modo, il grafo della struttura di un filesystem Unix può essere considerato molto simile a un grafo orientato o albero, con l'aggiunta di scorciatoie rappresentate da questi link.

Nomi dei file

Non esiste una regola generale precisa che stabilisca quali sono i caratteri che possono essere usati per nominare un file. Esiste solo un modo per (cercare di) stare fuori dai guai: il simbolo / non deve essere utilizzato essendo il modo con qui si separano i nomi all'interno di un percorso e conviene limitarsi all'uso delle lettere dell'alfabeto inglese non accentate, dei numeri, del punto e del segno di sottolineatura.

Per convenzione, nei sistemi Unix, i file che iniziano con un punto, sono classificati come ``nascosti'' e vengono mostrati e utilizzati solo quando espressamente richiesti.

<!>   Questi file, quelli che iniziano con un punto, sono nascosti per una buona ragione: si vuole evitare che utilizzando i caratteri jolly si faccia riferimento alla directory corrente (.) e alla directory precedente (..). Nello stesso modo si deve fare molta attenzione quando di vuole fare riferimento a questi file nascosti. Il comando rm -r .* non si limita a eliminare i file e le directory che iniziano con un solo punto iniziale, ma elimina anche . e .., cioè, alla fine, l'intero filesystem.

Permessi

I file di un filesystem Unix hanno un utente e un gruppo proprietari. L'utente proprietario può modificare i permessi di accesso ai suoi file, limitando questi anche per se stesso.

Si distinguono tre tipi di accesso: lettura, scrittura, esecuzione. Il significato del tipo di accesso dipende dal file cui questo si intende applicare.

Per i file normali:

Per le directory:

I permessi di un file permettono di attribuire privilegi differenti a seconda che l'utente sia il proprietario del file, appartenga al gruppo proprietario

Per gruppo proprietario si intende quello dell'utente proprietario.
o sia un utente diverso da questi. Si hanno quindi tre livelli differenti. I permessi si possono esprimere in due forme diverse: attraverso una stringa alfabetica o un numero.

Permessi espressi in forma di stringa

I permessi possono essere rappresentati attraverso una stringa di nove caratteri in cui possono apparire le lettere r, w, x oppure un trattino (-). La presenza della lettera r indica un permesso in lettura, la lettera w indica un permesso in scrittura, la lettera x indica un permesso in esecuzione.

I primi tre caratteri della stringa rappresentano i privilegi concessi al proprietario stesso, il gruppetto di tre caratteri successivo rappresenta i privilegi degli utenti appartenenti al gruppo, il gruppetto finale di tre caratteri rappresenta i privilegi concessi agli altri utenti.

Esempi

rw-r--r--

L'utente proprietario può accedervi in lettura e scrittura, mentre sia gli appartenenti al gruppo che gli altri utenti possono solo accedervi in lettura.

rwxr-x---

L'utente proprietario può accedervi in lettura, scrittura ed esecuzione; gli utenti appartenenti al gruppo possono accedervi in lettura e in esecuzione; gli altri utenti non possono accedervi in alcun modo.

rw-------

L'utente proprietario può accedervi in lettura e scrittura, mentre tutti gli altri non possono accedervi affatto.

Permessi espressi in forma numerica

I permessi possono essere rappresentati attraverso una serie di tre cifre numeriche, in cui la prima rappresenta i privilegi dell'utente proprietario, la seconda quelli del gruppo e la terza quelli degli altri utenti. Il permesso di lettura corrisponde al numero 4, il permesso di scrittura corrisponde al numero 2, il permesso di esecuzione corrisponde al numero 1. Il numero che rappresenta il permesso attribuito ad un tipo di utente, si ottiene sommando i numeri corrispondenti ai privilegi che si vogliono concedere.

Esempi

644

L'utente proprietario può accedervi in lettura e scrittura (4+2), mentre sia gli appartenenti al gruppo che gli altri utenti possono solo accedervi in lettura.

750

L'utente proprietario può accedervi in lettura, scrittura ed esecuzione (4+2+1); gli utenti appartenenti al gruppo possono accedervi in lettura e in esecuzione (4+1); gli altri utenti non possono accedervi in alcun modo.

600

L'utente proprietario può accedervi in lettura e scrittura (4+2), mentre tutti gli altri non possono accedervi affatto.

S-bit

I permessi dei file sono memorizzati in una sequenza di 9 bit, dove ogni gruppetto di tre rappresenta i permessi per una categoria di utenti (il proprietario, il gruppo, gli altri).

Assieme a questi 9 bit ne esistono altri tre, posti all'inizio, che permettono di indicare: il SUID (Set User ID), il SGID (Set Group ID) e lo sticky bit. Si tratta di attributi speciali che riguardano solo i file eseguibili. Solitamente non vengono usati e per lo più gli utenti normali ignorano che esistano.

Tutto questo serve adesso per sapere il motivo per il quale spesso i permessi espressi in forma numerica (ottale) sono di quattro cifre, con la prima normalmente azzerata.

Per esempio, la modalità 0644 rappresenta il permesso per l'utente proprietario di accedervi in lettura e scrittura e per gli altri utenti di accedervi in sola lettura.

L'indicazione della presenza di questi bit attivati può essere vista anche nelle rappresentazioni in forma di stringa. L'elenco seguente mostra il numero ottale e la sigla corrispondente.

Come si può osservare, questa indicazione prende il posto del permesso in esecuzione. Nel caso in cui, il permesso in esecuzione corrispondente non sia attivato, la lettera (s o t) appare maiuscola.

Date

Tra gli attributi di un file ci sono anche tre indicazioni data-orario:

2.7 Login - logout

Una volta avviato un sistema Unix, prima che sia disponibile il prompt della shell, occorre che l'utente sia riconosciuto dal sistema, attraverso la procedura di login. Quello che viene chiesto è l'inserimento del nome dell'utente (così come è stato registrato) e subito dopo la parola chiave (password) abbinata a quell'utente. Eccezionalmente può trattarsi di un utente senza password, così come avviene per i mini sistemi a dischetti fatti per consentire le operazioni di manutenzione eccezionale.

Si distingue solo tra due tipi di utenti: l'amministratore, il cui nome è root, e gli altri utenti. L'utente root non ha alcun limite di azione, gli altri utenti dipendono dai permessi attribuiti ai file (e directory) oltre che dai vincoli posti direttamente da alcuni programmi.

In teoria, è possibile usare un computer personale solo utilizzando i privilegi dell'utente root. In pratica, questo non conviene perché si perde di vista il significato della gestione dei permessi sui file (e directory) e soprattutto si rendono vani i sistemi di sicurezza predefiniti contro gli errori. Per comprendere meglio questo concetto, basta pensare a cosa succede in un sistema Dos quando si esegue un comando come quello seguente.

C:\> DEL *.*

Prima di iniziare la cancellazione, il Dos chiede una ulteriore conferma proprio perché non esiste alcun tipo di controllo. In un sistema Unix, di solito ciò non avviene: la cancellazione viene eseguita immediatamente senza richiesta di conferme. Se i permessi consentono la cancellazione dei file solo a root, un utente registrato in modo diverso non può fare alcun danno.

In conclusione, l'utente root deve stare molto attento a quello che fa proprio perché può accedere a qualunque funzione o file del sistema, e il sistema non pone alcuna obbiezione al suo comportamento. Un utente normale, è invece vincolato dai permessi sui file e dai programmi che possono impedirgli di eseguire certe attività, di conseguenza, è possibile lavorare con meno attenzione.

adduser

Di solito, nelle distribuzioni Linux, si trova la utility adduser che consente all'utente root di aggiungere un nuovo utente. Il nome dell'utente non deve superare gli otto caratteri e tutti gli altri dati richiesti possono essere semplicemente lasciati al loro valore predefinito. Dopo la prima installazione di Linux, è importante creare il proprio account personale per poter usare il sistema senza i privilegi che ha l'amministratore.

exit

La shell comprende solitamente il comando exit che ne termina l'esecuzione. Se si tratta di una shell avviata automaticamente subito dopo il login, il sistema provvederà a chiedere un nuovo login.

2.8 Interpretazione dei comandi

Come già s'era detto, l'interpretazione dei comandi è compito della shell. L'interpretazione dei comandi implica la sostituzione di alcuni simboli che hanno un significato speciale.

File globbing

Il globbing è il metodo attraverso il quale, tramite un modello simbolico, è possibile indicare un gruppo di nomi di file. Corrisponde all'uso dei caratteri jolly del Dos, con la differenza fondamentale, che è la shell ad occuparsi della loro sostituzione e non i programmi. Di solito, si possono utilizzare i simboli seguenti.

*

L'asterisco rappresenta un gruppo qualsiasi di caratteri, compreso il punto, purché questo punto non si trovi all'inizio del nome.

?

Il punto interrogativo rappresenta un unico carattere qualsiasi, compreso il punto, purché questo punto non si trovi all'inizio del nome.

[...]

Le parentesi quadre permettono di rappresentare un carattere qualsiasi tra quelli contenuti al loro interno, o un intervallo di caratteri possibili.

Conseguenze nella sintassi dei comandi

Dal momento che è la shell a eseguire la sostituzione dei caratteri jolly, la sintassi tipica di un programma di utilità è la seguente.

<programma> [<opzioni>] [<file>... ]

Nei sistemi Dos si usa spesso la convenzione inversa, secondo cui l'indicazione dei file avviene prima delle opzioni. Da un punto di vista puramente logico, potrebbe sembrare più giusto l'approccio del Dos: si indica l'oggetto su cui agire e quindi si indica il modo. Facendo così si ottengono però una serie di svantaggi:

In pratica, il tipo di semplificazione utilizzato dal Dos è poi la fonte di una serie di complicazioni per i programmatori e gli utilizzatori.

Tilde

Di solito, la shell si occupa di eseguire la sostituzione del carattere tilde (~). Nei sistemi Unix, ogni utente ha una cosiddetta directory home. Il simbolo ~ da solo viene sostituito dalla shell con la directory home dell'utente che sta utilizzando il sistema, mentre un nome di utente preceduto dal simbolo ~, viene sostituito dalla shell con la directory home dell'utente indicato.

Variabili di ambiente

Le variabili di ambiente sono gestite dalla shell e costituiscono uno dei modi attraverso cui si configura un sistema. I programmi possono leggere alcune variabili di loro interesse e modificare il proprio comportamento in base al loro contenuto.

Una riga di comando può fare riferimento a una variabile di ambiente: la shell provvede a sostituirne l'indicazione con il suo contenuto.

2.9 Ridirezione e pipeline

I programmi, quando vengono eseguiti, hanno a disposizione alcuni canali standard per il flusso dei dati (input/output). Questi sono: standard input, standard output e standard error.

Lo standard input è di norma rappresentato dai dati provenienti dalla tastiera del terminale. Lo standard output e lo standard error sono normalmente emessi sullo schermo del terminale.

Per mezzo della shell, si possono eseguire delle ridirezioni di questi flussi di dati, facendo in modo per esempio, che lo standard output per un programma sia connesso allo standard input di un altro, creando in questo caso una pipeline.

Ridirezione dello standard input

<programma> < <file-di-dati>

Si ridirige lo standard input utilizzando il simbolo ``minore'' (<) seguito dalla fonte alternativa di dati. Il programma a sinistra del simbolo < riceve come standard input il contenuto del file indicato a destra.

Esempi

$ sort < elenco.txt

Visualizza il contenuto del file elenco.txt dopo averlo riordinato.

Ridirezione dello standard output

<programma> > <file-di-dati>

Si ridirige lo standard output utilizzando il simbolo ``maggiore'' (>) seguito dalla destinazione alternativa dei dati. Il programma a sinistra del simbolo > emette il suo standard output all'interno del file indicato a destra che viene creato per l'occasione.

Lo standard output può essere aggiunto a un file preesistente; in tal caso si utilizza il simbolo >>.

Esempi

$ ls > elenco.txt

Genera il file elenco.txt con il risultato dell'esecuzione di ls.

$ ls >> elenco.txt

Aggiunge al file elenco.txt il risultato dell'esecuzione di ls.

Ridirezione dello standard error

<programma> 2> <file-di-dati>

Si ridirige lo standard error utilizzando il simbolo 2> seguito dalla destinazione alternativa dei dati. Il programma a sinistra del simbolo 2> emette il suo standard error all'interno del file indicato a destra che viene creato per l'occasione.

Lo standard error può essere aggiunto a un file preesistente; in tal caso si utilizza il simbolo 2>>.

Esempi

$ controlla 2> errori.txt

Genera il file errori.txt con il risultato dell'esecuzione dell'ipotetico programma controlla.

$ controlla 2>> errori.txt

Aggiunge al file errori.txt il risultato dell'esecuzione dell'ipotetico programma controlla.

Pipeline

<programma1> | <programma2> [ | <programma3>... ]

Si ridirige lo standard output di un programma nello standard input di un altro, utilizzando il simbolo ``barra verticale'' (|). Il programma a sinistra del simbolo | emette il suo standard output nello standard input di quello che sta a destra.

<!>   Nella rappresentazione schematica delle sintassi dei programmi, questo simbolo ha normalmente il significato di una scelta alternativa tra opzioni diverse, parole chiave o altri argomenti. In questo caso fa proprio parte della costruzione di una pipeline.

Esempi

$ ls | sort

Riordina il risultato del comando ls.

$ ls | sort | less

Riordina il risultato del comando ls e quindi lo fa scorrere sullo schermo con l'aiuto del programma less.

2.10 Comandi e programmi di utilità di uso comune

In linea di principio, con il termine ``comando'' ci si dovrebbe riferire ai comandi interni di una shell, mentre con il termine utility, o programma, si dovrebbe fare riferimento a programmi eseguibili esterni alla shell. Di fatto però, dal momento che si mette in esecuzione un programma impartendo un comando alla shell, spesso con questo termine, si fa riferimento in maniera indistinta a comandi interni di shell o (in mancanza) a ``comandi esterni'' o utility.

Naturalmente, questo ragionamento vale fino a quando si tratta di utility di uso comune, non troppo complesse che usano un sistema di input/output elementare. Sarebbe un po' difficile definire ``comando'' un programma di scrittura o un navigatore web.

Interpretazione della sintassi

La sintassi di un programma o di un comando segue delle regole molto semplici.

Naturalmente, può capitare che i simboli utilizzati per rappresentare la sintassi, servano negli argomenti di un comando o di un programma. I casi più evidenti sono: Quando ciò accade, occorre fare attenzione al contesto per poter interpretare correttamente il significato di una sintassi.

Organizzazione tipica

Il tipico programma di utilità ha la sintassi seguente.

programma [<opzioni>] [<file>... ]

In questo caso, il nome del programma è proprio programma.

Opzioni

Normalmente vengono accettate una o più opzioni facoltative, espresse attraverso una lettera dell'alfabeto preceduta da un trattino (-a, -b, ...). Queste possono essere usate separatamente o raggruppandole con un unico trattino seguito da tutte le lettere delle opzioni che si intendono selezionare. Quindi:

programma -a -b

è traducibile nel comando seguente.

programma -ab

I programmi più recenti includono opzioni descrittive formate da un nome preceduto da due trattini. In presenza di questi tipi di opzioni, non si possono fare aggregazioni nel modo appena visto.

A volte si incontrano opzioni che richiedono l'indicazione aggiuntiva di un altro argomento.

File

La maggior parte dei programmi di utilità esegue delle elaborazioni su file, generando un risultato che normalmente viene emesso attraverso lo standard output. Spesso, quando non vengono indicati file negli argomenti, l'input per l'elaborazione viene ottenuto dallo standard input.

2.11 L'ABC dei comandi Linux

Nelle sezioni seguenti vengono descritti in modo sommario alcuni programmi di utilità fondamentali. Gli esempi mostrati fanno riferimento all'uso della shell bash che attualmente costituisce lo standard per Linux.

È importante ricordare che negli esempi si utilizza un prompt differente a seconda che ci si riferisca a un comando impartito da parte di un utente normale o da parte dell'amministratore: il dollaro ($) rappresenta una azione di un utente normale, mentre il simbolo # rappresenta una azione dell'utente root.

ls

ls [<opzioni>] [<file>... ]

Elenca i file contenuti in una directory.

Esempi

$ ls

Elenca il contenuto della directory corrente.

$ ls -l *.doc

Elenca tutti i file che terminano con il suffisso .doc e si trovano nella directory corrente. L'elenco contiene più dettagli sui file essendoci l'opzione -l.

cd

cd [<directory>]

Cambia la directory corrente.

Esempi

$ cd /tmp

Cambia la directory corrente, facendola diventare /tmp.

$ cd ciao

Cambia la directory corrente, spostandosi nella directory ciao che discende da quella corrente.

$ cd ~

Cambia la directory corrente, spostandosi nella directory home dell'utente.

$ cd ~daniele

Cambia la directory corrente, spostandosi nella directory home dell'utente daniele.

mkdir

mkdir [<opzioni>] <directory>...

Crea una directory.

Esempi

$ mkdir paperoga

Crea la directory paperoga, come discendente di quella corrente.

$ mkdir /paperino/paperoga

Crea la directory paperoga, come discendente di /paperino.

$ mkdir ~/paperoga

Crea la directory paperoga, come discendente della directory home dell'utente attuale.

cp

cp [<opzioni>] <origine>... <destinazione>

Copia uno o più file (incluse le directory) in una unica destinazione.

<!>   La copia in un sistema Unix non funziona come nei sistemi Dos, e ciò principalmente a causa di due fattori: il file globbing viene risolto dalla shell prima dell'esecuzione del comando e i filesystem Unix possono utilizzare i link simbolici.

Se vengono specificati solo i nomi di due file normali, il primo viene copiato sul secondo, viene cioè generata una copia che ha il nome indicato come destinazione. Se il secondo nome indicato è una directory, il file viene copiato nella directory, con lo stesso nome di origine. Se vengono indicati più file, l'ultimo nome deve essere una directory e verranno generate le copie di tutti i file indicati, all'interno della directory di destinazione. Di conseguenza, quando si utilizza il file globbing, la destinazione deve essere una directory. In mancanza di altre indicazioni attraverso l'uso di opzioni adeguate, le directory non vengono copiate.

<!>   Chi utilizzava il Dos potrebbe essere abituato ad usare il comando COPY per copiare un gruppo di file in un altro gruppo di file con i nomi leggermente diversi, come in questo esempio: COPY *.bak *.doc. Con i sistemi Unix, questo tipo di approccio non può funzionare.

I file elencati nell'origine, potrebbero essere in realtà dei link simbolici. Se non viene specificato diversamente attraverso l'uso delle opzioni, questi vengono copiati così come se fossero file normali; cioè la copia sarà ottenuta a partire dai file originali e non si otterrà quindi una copia dei link.

Alcune opzioni

-a

Equivalente a -dpR, utile per l'archiviazione o comunque per la copia di link simbolici così come sono.

-d

Copia i link simbolici mantenendoli come tali, invece di copiare il file a cui i link si riferiscono.

-f

Sovrascrittura forzata dei file di destinazione.

-l

Crea un hard link invece di copiare i file.

-p

Mantiene le proprietà e i permessi originali.

-r | -R

Copia file e directory in modo ricorsivo (includendo le sottodirectory).

Esempi

$ cp -r /test/* ~/prova

Copia il contenuto della directory /test in ~/prova copiando anche eventuali sottodirectory contenute in /test.

<!>   Se ~/prova esiste già e non si tratta di una directory, questo file viene sovrascritto, perdendo quindi il suo contenuto originale.

$ cp -r /test ~/prova

Copia la directory /test in ~/prova (attaccando test a ~/prova) copiando anche eventuali sottodirectory contenute in /test.

$ cp -dpR /test ~/prova

Copia la directory /test in ~/prova (attaccando test a ~/prova) copiando anche eventuali sottodirectory contenute in /test e mantenendo inalterati i permessi e gli eventuali link simbolici.

ln

ln [<opzioni>] <origine>... <destinazione>

Crea uno o più link di file (incluse le directory) in una unica destinazione.

<!>   La creazione di un link è una azione simile a quella della copia. Di conseguenza valgono le stesse considerazioni fatte in occasione del comando cp per quanto riguarda la differenza di comportamento che c'è tra Unix e Dos.

Se vengono specificati solo i nomi di due file normali, il secondo diventa il link del primo. Se il secondo nome indicato è una directory, al suo interno verranno creati altrettanti link quanti sono i file e/o directory indicati come sorgente. I nomi utilizzati saranno gli stessi dei sorgenti. Se vengono indicati più file, l'ultimo nome deve essere una directory.

È ammissibile la creazione di link che fanno riferimento ad altri link.

Si possono creare due tipi di link: hard e simbolici. Questi ultimi sono da preferire. Se non viene richiesto diversamente attraverso le opzioni, si generano degli hard link invece che i consueti link simbolici.

Alcune opzioni

-s

Crea un link simbolico.

Esempi

$ ln -s /test/* ~/prova

Crea, nella destinazione ~/prova, una serie di link simbolici corrispondenti a tutti i file e/o directory contenuti in /test.

$ cp -s /test ~/prova

Crea, nella destinazione ~/prova, un link simbolico corrispondente al file o alla directory /test. Se ~/prova è una directory, viene creato il link ~/prova/test; se ~/prova non esiste, viene creato il link ~/prova.

rm

rm [<opzioni>] <nome>...

Rimuove i file indicati come argomento. In mancanza dell'indicazione delle opzioni necessarie, non vengono rimosse le directory.

Alcune opzioni

-r | -R

Rimuove il contenuto delle directory in modo ricorsivo.

Esempi

$ rm prova

Elimina il file prova.

$ rm ./-r

Elimina il file -r che inizia il suo nome con un trattino, senza confondersi con l'opzione -r (ricorsione).

$ rm -r ~/varie

Elimina la directory varie che risiede nella directory home, insieme a tutte le sue eventuali sottodirectory.

Attenzione

# rm -r .*

Elimina tutti i file e le directory a partire dalla radice! In pratica elimina tutto.

Questo è un errore tipico di chi vuole cancellare tutte le directory nascoste (cioè quelle che iniziano con un punto) contenute nella directory corrente. Il disastro avviene perché nei sistemi Unix, .* rappresenta anche la directory corrente (.) e la directory precedente o genitrice (..).

mv

mv [<opzioni>] <origine>... <destinazione>

Sposta i file e/o le directory. Se vengono specificati solo i nomi di due elementi (file o directory), il primo viene spostato e/o rinominato in modo da ottenere quanto indicato come destinazione. Se vengono indicati più elementi (file o directory), l'ultimo attributo deve essere una directory: verranno spostati tutti gli elementi elencati nella directory di destinazione. Nel caso di spostamenti attraverso filesystem differenti, vengono spostati solo i cosiddetti file normali (quindi: no link, no directory).

<!>   Nei sistemi Unix non esiste la possibilità di rinominare un file o una directory semplicemente come avviene nel Dos. Per cambiare un nome, occorre spostarlo. Questo fatto ha poi delle implicazioni nella gestione dei permessi delle directory.

Esempi

$ mv prova prova1

Cambia il nome del file (o della directory) prova in prova1.

$ mv * /tmp

sposta tutti i file e directory contenuti nella directory corrente, all'interno di /tmp.

cat

cat [<opzioni>] [<file>... ]

Concatena dei file e ne emette il contenuto nello standard output. Il comando emette di seguito i file indicati come argomento attraverso lo standard output (sullo schermo), in pratica qualcosa di simile al comando TYPE del Dos. Se non viene fornito il nome di alcun file, viene utilizzato lo standard input.

Esempi

$ cat prova prova1

Mostra di seguito il contenuto di prova e prova1.

$ cat prova prova1 > prova2

Genera il file prova2 come risultato del concatenamento in sequenza di prova e prova1.

2.12 Glossario

Account

Il termine account rappresenta letteralmente un conto, come quello che si può avere in banca. All'interno di un sistema operativo Unix, si ha un account quando si è stati registrati (e di conseguenza è stato ottenuto un UID) ed è possibile accedere attraverso la procedura di login.

Case sensitive | case insensitive

Con queste due definizioni si intende riferirsi rispettivamente alla ``sensibilità'' o meno verso la differenza tra le lettere maiuscole e minuscole. Generalmente, i sistemi Unix sono sensibili a questa differenza, ma esistono circostanze in cui questa non c'è o si vuole ignorare.

Daemon o demone

Il daemon, o demone, è un programma che funziona in background (o in sottofondo) e compie dei servizi in modo ripetitivo, come in un circolo vizioso. Questo termine è tipico degli ambienti Unix, mentre con altri sistemi operativi si utilizzano altri termini, quale quello di server. Per tradizione, la maggior parte dei programmi daemon ha un nome che termina con la lettera d.

Espressione regolare

L'espressione regolare (si veda l'appendice `Espressioni regolari') è un modo per definire la ricerca di stringhe attraverso un modello. Viene usata da diversi programmi di utilità.

GID

Group ID o numero identificativo del gruppo di utenti.

Globbing - caratteri jolly

Quando si vuole identificare un gruppo di file (e/o directory) attraverso una sola definizione si utilizza il meccanismo del globbing, corrispondente in ambiente Dos all'uso dei caratteri jolly. Si tratta di solito dell'asterisco, del punto interrogativo e delle parentesi quadre.

Job

Il termine job viene usato spesso nella documentazione Unix in riferimento a ``compiti'' di vario tipo, a seconda del contesto.

Job di shell

Le shell POSIX e in particolare bash sono in grado di gestire i job di shell che rappresentano un insieme di processi generati da un singolo comando.

Job di stampa

Si tratta di stampe accodate nel cosiddetto spool di stampa (coda di stampa).

Job di scheduling

Si tratta di comandi la cui esecuzione è stata pianificata per un certo orario o accodata in attesa di risorse disponibili.

Le situazioni in cui il termine job viene adoperato possono essere anche altre, ma gli esempi indicati bastano per intendere l'ampiezza del significato.

Log

In informatica, il log equivale al ``diario di bordo'' delle navi. Il log è quindi un sistema automatico di registrazione di avvenimenti significativi. I file che contengono queste annotazioni, sono detti file di log.

Mount e unmount

Nei sistemi operativi Unix, quando si vuole accedere ai dati memorizzati su disco, non si può fare riferimento a un file appartenente a una certa unità come avviene nei sistemi Dos e derivati. Si deve sempre fare riferimento al filesystem globale. Per fare questo, tutti i dischi a cui si vuole accedere devono essere collegati tramite un procedimento simile all'innesto di rami. Il termine mount indica un collegamento del contenuto di un disco nel filesystem globale; il termine unmount indica lo scollegamento o il distacco di un disco dalla struttura globale.

MTU - Max Transfer Unit

Definisce la dimensione massima in byte dei frame che possono essere inviati nella rete attraverso una certa interfaccia.

Newline

Con questo termine si vuole fare riferimento al codice necessario per indicare la fine di una riga di testo e l'inizio di quella successiva. Utilizzando questo nome si evita di fare riferimento in modo diretto al codice effettivo in modo che il concetto possa essere adatto a diversi sistemi.

Linux, come tutti i sistemi tradizionali della famiglia Unix, utilizza il codice <LF>. Nei sistemi Dos e discendenti si utilizza invece la coppia <CR><LF>, per cui, se si tenta di stampare un testo fatto per i sistemi Unix utilizzando una stampante configurata per operare con il sistema operativo Dos, come risultato si otterranno una serie di righe scalettate.

Per ovviare all'inconveniente, tenendo conto che raramente una stampante del genere può essere configurata per andare a capo con il solo codice <LF>, è possibile utilizzare un filtro che trasformi il carattere <LF> in <CR><LF>. Il programma filtro è abbastanza noto e si chiama unix2dos e può essere utilizzato nel modo seguente.

$ unix2dos < testo.txt | lpr

NFS

Un servizio molto importante nelle reti locali è dato dalla possibilità di condividere porzioni di filesystem da e verso altri computer connessi. Questo servizio è dato dal protocollo NFS e consente quindi la condivisione di dati attraverso la rete.

NFS viene spesso indicato come acronimo di Network File System e in alcuni casi di Network File Sharing.

Le due possibili interpretazioni rappresentano due aspetti della stessa cosa: l'utilizzo di un filesystem che si estende attraverso la rete e la condivisione dei dati che ne deriva.

NNTP

Network News Transfer Protocol. Si tratta del protocollo che si occupa di trasmettere i messaggi di news. Un NNTP server è un computer che si occupa di raccogliere una copia dei messaggi news e di consentire agli utenti di leggere e inviare messaggi all'interno di questi news.

Password

Si riferisce a una parola utilizzata come mezzo di verifica dell'identificazione per poter accedere a un servizio di qualunque genere. Può apparire tradotta in vari modi.

PID

Process ID o numero identificativo del processo.

Pipe - pipeline

Si tratta di una tubazione immaginaria attraverso la quale si convoglia l'output di un programma verso l'input di un altro. La connessione di più programmi in questo modo è compito della shell e di solito si utilizza il simbolo | per indicare questa operazione. Per lo stesso motivo, quando il contesto lo consente, il simbolo | viene anche chiamato pipe.

Record

Il record è in generale una registrazione di qualunque genere. In informatica, il record corrisponde ad una ``riga'' di un file di dati. Un record è normalmente suddiviso in campi o field, per cui si può fare una analogia con un archivio a schede: l'archivio è il file, le schede sono i record e i campi sono i vari elementi indicati nelle schede.

Regular file

Nei sistemi operativi della famiglia Unix, quando si parla di file, si intendono anche le directory oltre che altri oggetti che hanno funzioni specifiche. Per specificare che si parla di un file puro e semplice, comprendendo in questa categoria anche gli eseguibili, si parla di regular file o di file normale.

Run level o livello di esecuzione

Quando si utilizza una procedura di inizializzazione in stile System V, che è poi quella normale, si distinguono diversi ``livelli di esecuzione'', in modo da poter definire quali parti del sistema devono essere attivate e quali no, a seconda delle esigenze.

I livello di esecuzione è un numero positivo che parte da zero, il cui significato dipende dal modo in cui il sistema è configurato. Di solito il livello 0 è riservato per la fase di preparazione allo spegnimento, il livello 1 è riservato al funzionamento monoutente e il livello 6 è riservato alla fase di preparazione al riavvio del sistema.

Shell

La shell di un sistema operativo è quel programma che si occupa di interpretare e eseguire i comandi dati dall'utente, attraverso una riga di comando. Il termine shell, utilizzato per questo scopo, nasce proprio dai sistemi operativi Unix.

SMTP

Send Mail Transfer Protocol. Si tratta del protocollo che si occupa di trasmettere la posta elettronica. Un SMTP server è un computer che si occupa di gestire la posta di un certo gruppo di utenti i quali utilizzano quel computer come loro centrale della posta.

Standard error

Il file o il dispositivo predefinito per l'emissione dei dati relativi a segnalazioni di errore è lo standard error. Di solito si tratta del video della console o del terminale da cui si opera. Lo standard error, di norma, può essere ridiretto utilizzando il simbolo 2> seguito dal nome del file o del dispositivo da utilizzare.

Standard input

Il file o il dispositivo predefinito per l'inserimento dei dati, è lo standard input. Di solito è la tastiera della console o del terminale da cui si opera. Per terminare l'inserimento occorre fornire il carattere di fine file (^D) che di solito si ottiene con la combinazione [Ctrl+d].

Lo standard input, di norma, può essere ridiretto utilizzando il simbolo ``minore'' (<) seguito dal nome del file o del dispositivo da utilizzare, oppure utilizzando il simbolo pipe (|) quando si vuole utilizzare l'output di un comando come input per il comando successivo.

Standard output

Il file o il dispositivo predefinito per l'uscita dei dati, è lo standard output. Di solito è il video della console o del terminale da cui si opera. Lo standard output, di norma, può essere ridiretto utilizzando il simbolo ``maggiore'' (>) seguito dal nome del file o del dispositivo da utilizzare, oppure può essere diretto ad un comando seguente attraverso il simbolo pipe (|).

Terminale o tty

Alle origini, il modo normale per interagire con un computer era l'uso della telescrivente: teletype. Da questo nome deriva la sigla tty usata normalmente per identificare un terminale generico. La console è il terminale principale che fa parte del computer stesso. Quando si parla di terminale si intende attualmente un complesso formato da una tastiera e un video.

Quando si parla di un flusso di dati proveniente da un terminale, come nel caso dello standard input, si fa riferimento a quanto inserito tramite la tastiera. Quando si parla di un flusso di dati verso un terminale, come nel caso dello standard output, si fa riferimento a quanto viene emesso sullo schermo.

UID

User ID o numero identificativo dell'utente.

Utility

Una utility, ovvero un programma di utilità, è un programma ``utile'' e pratico, che svolge il suo compito senza tanti fronzoli e senza essere troppo appariscente. Di solito, i programmi di questo tipo, sono quelli che fanno parte integrante del sistema operativo.

 

1997.10.26 - Scritto da Daniele Giacomini   daniele@calion.com   (vedi copyright: Appunti Linux).


Capitolo successivo Capitolo precedente Indice