[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico] [volume] [parte]


Capitolo 19.   Introduzione a Unix e ai sistemi GNU in particolare

Per sistemi GNU si intendono qui quei sistemi operativi basati principalmente sul lavoro del progetto GNU (<http://www.gnu.org>). In particolare, fanno parte di questo gruppo di sistemi GNU/Linux e GNU/Hurd.

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.

Quando si fa riferimento a sistemi Unix, in generale si intende qualcosa che riguarda anche i sistemi GNU.

19.1   Distinzione tra lettere maiuscole e lettere minuscole

Nei sistemi operativi Unix i nomi dei file 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-Windows, che preservano l'indicazione delle lettere maiuscole o minuscole, ma poi non fanno differenza quando si vuole fare riferimento a quei file.

Quando in un contesto si fa differenza tra maiuscole e minuscole, capita spesso di vederlo definito come case sensitive, mentre per converso, quando non si fa differenza, come case insensitive.

19.2   Root

Negli ambienti Unix si fa spesso riferimento al termine root in vari contesti e con significati differenti. Root è la radice, o l'origine, senza altri significati. A seconda del contesto, ne rappresenta l'origine, o il punto iniziale. Per esempio, si può avere:

Le situazioni in cui si presenta questa definizione possono essere molte di più. L'importante, per ora, è avere chiara l'estensione del significato di questa parola.

19.3   Utenti

Generalmente, i sistemi Unix sono 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 ciò che vuole, soprattutto rischia di produrre gravi danni anche solo per piccole disattenzioni.

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

19.3.1   Registrazione dell'utenza

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

Dal punto di vista dell'utente, l'account è un nome abbinato a una parola d'ordine che gli permette di essere riconosciuto e quindi di poter accedere. Oltre a questo, l'account stabilisce l'appartenenza a un gruppo di utenti.

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

19.3.2   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 di utilizzare il sistema in qualità di utente amministratore (root) anche quando si è l'unico utilizzatore del proprio elaboratore.

19.3.3   Utenti e gruppi

Tutti gli utenti di un sistema Unix sono associati a uno o più gruppi. Un utente ottiene dei privilegi in quanto tale, oppure in quanto appartenente a un certo gruppo.

Figura 19.1. Utenti e gruppi: un utente può appartenere a gruppi differenti.

utenti e gruppi

19.4   Composizione

Un sistema Unix comune, è composto almeno da:

19.4.1   Avvio

Il boot è il modo con cui un sistema operativo può essere avviato quando l'elaboratore viene acceso. Di solito, il software registrato su ROM degli elaboratori basati sull'uso di unità di memorizzazione di massa ad accesso diretto, è fatto in modo da eseguire le istruzioni contenute nel primo settore, della prima di tali unità previste. Questo settore è noto come MBR (Master boot record). Il codice contenuto nel settore di avvio provvede all'esecuzione del kernel (lo avvia).

La parola boot è il risultato dell'abbreviazione di bootstrap. La parola, usata normalmente al plurale, si riferisce alle linguette degli stivali che servono a calzarli (calzastivali), senza bisogno di aiuto da parte di una seconda persona. Questo fa sì che il termine venga usato in inglese anche per esprimere il concetto di «cavarsela da soli», che spiega il motivo della scelta nel contesto informatico.

In base all'analogia, anche se il suo utilizzo è desueto, è il caso di osservare che il bootstrap è il programma o il codice che si prende cura del caricamento del sistema operativo. Pertanto, sarebbe come dire che programmi come LILO e GRUB, installano il bootstrap.

Con un sistema GNU installato in un elaboratore x86, la configurazione e la gestione del sistema di avvio viene fatta principalmente attraverso:

19.4.2   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 file unico, il cui nome potrebbe essere vmlinuz (oppure zImage, bzImage 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) per i quali è stato predisposto, quindi innesta (mount) il file system principale (root) e infine avvia la procedura di inizializzazione del sistema (Init).

19.4.3   File system

Il file system è 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 un'unità di memorizzazione e un'altra, come avviene nel Dos, in cui i dischi o le partizioni sono contrassegnati da una lettera dell'alfabeto (A:, B:, C:). Nei sistemi Unix, tutti i file system cui si vuole poter accedere devono essere concatenati assieme, in modo da formare un solo file system globale.

Quando un sistema Unix viene avviato, si attiva il file system principale, o root, quindi possono essere collegati a questo altri file system a partire da una directory o sottodirectory di quella principale. Dal momento che per accedere ai dati di un file system diverso da quello principale occorre che questo sia collegato, nello stesso modo, per poter rimuovere l'unità di memorizzazione contenente questo file system, occorre interrompere il 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 file system del dischetto, quindi lo si può usare come parte dell'unico file system globale. Al termine si deve interrompere questo collegamento e solo allora si può rimuovere il dischetto.

Figura 19.2. Collegamento di un file system secondario in corrispondenza di un punto di innesto (o mount point).

innesto di un file system

L'operazione con cui si collega un file system secondario nel file system globale viene detta mount, per cui si utilizza normalmente il verbo montare o innestare con questo significato; l'operazione inversa viene detta unmount e conseguentemente si utilizza il verbo smontare o staccare. La directory a partire dalla quale si inserisce un altro file system è il mount point, che potrebbe essere definito come il punto di innesto.

19.4.4   Inizializzazione e gestione dei processi

I sistemi Unix funzionano generalmente in multiprogrammazione, ovvero multitasking, pertanto sono in grado di eseguire diversi programmi, o processi elaborativi, contemporaneamente. Per poter realizzare questo, esiste un gestore dei processi elaborativi: Init, realizzato in pratica dall'eseguibile init, che viene avviato subito dopo l'attivazione del file system principale, allo scopo di occuparsi di eseguire la procedura di inizializzazione del sistema. In pratica, esegue una serie di istruzioni necessarie alla configurazione corretta del sistema particolare che si sta avviando.

19.4.5   Demone

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 demoni (daemon).

19.4.6   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 demoni attivati in fase di inizializzazione del sistema. Nei sistemi GNU, i servizi di rete sono controllati fondamentalmente da tre programmi:

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

19.4.7   Registrazione e controllo degli accessi

I sistemi Unix, oltre che essere in multiprogrammazione 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 dell'elaboratore attraverso la console, terminali locali connessi attraverso porte seriali (eventualmente anche attraverso la mediazione di modem), terminali locali o remoti connessi attraverso una rete.

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

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

19.4.8   Shell: interprete dei comandi

Ciò che permette a un utente di interagire con un sistema operativo è la shell, che si occupa di interpretare ed 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 tipica dei sistemi Unix è una shell derivata da quella di Bourne, possibilmente aderente allo standard POSIX: la shell POSIX. Nei sistemi GNU la shell tipica è Bash (il programma eseguibile bash), che è conforme allo standard POSIX.

Una shell Unix normale svolge i compiti seguenti:

19.4.9   Programmi di servizio 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 servizio sono quelli che di solito hanno piccole dimensioni, sono destinati a scopi specifici di amministrazione del sistema o anche solo di uso comune.

I programmi di servizio di uso comune sono contenuti solitamente all'interno delle directory /bin/ e /usr/bin/. Quelli riservati all'uso da parte dell'amministratore del sistema, l'utente root, sono contenuti normalmente in /sbin/ e /usr/sbin/ dove la lettera «s» iniziale, sta per superuser, con un chiaro riferimento all'amministratore.

19.4.10   Gestione della stampa

I sistemi operativi in multiprogrammazione (multitasking) predisposti per l'uso di una stampante, di norma gestiscono questa funzione attraverso una coda di stampa (spool). Tradizionalmente, i sistemi Unix utilizzano un demone denominato lpd per la gestione della stampa, in grado anche di ricevere richieste di stampa remote e di inviare richieste di stampa a elaboratori remoti.

19.4.11   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 dei sistemi Unix, 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.

19.5   Arresto o riavvio del sistema

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

Normalmente, in un sistema Unix solo l'utente root può avviare la procedura di arresto del sistema con il comando seguente:

shutdown -h now[Invio]

Per richiedere il riavvio del sistema:

shutdown -r now[Invio]

Con un sistema GNU/Linux installato su un elaboratore con architettura x86, di solito è possibile usare la combinazione di tasti [Ctrl Alt Canc] per riavviare il sistema. In questo modo, anche un utente comune ha modo di spegnere il sistema senza creare danni.

19.6   Dispositivi

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

Esistono due categorie fondamentali di file di dispositivo:

Il dispositivo a caratteri tipico è la console o la porta seriale, mentre il dispositivo a blocchi tipico è l'unità di memorizzazione di massa ad accesso diretto. A titolo di esempio, la tabella 19.3 mostra l'elenco di alcuni nomi di file di dispositivo di un sistema GNU/Linux.

Tabella 19.3. Alcuni nomi di dispositivo utilizzati da GNU/Linux.

Dispositivo Descrizione

/dev/fd0
la prima unità a dischetti

/dev/fd0u1440
unità a dischetti con l'indicazione esplicita del formato: 1 440 Kibyte

/dev/hda
il primo disco fisso ATA (IDE)

/dev/hda1
la prima partizione del primo disco fisso ATA (IDE)

/dev/hdb
il secondo disco fisso ATA (IDE)

/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 GNU/Linux

/dev/lp1
la seconda porta parallela dal punto di vista di GNU/Linux

/dev/ttyS0
la prima porta seriale

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.

I nomi utilizzati per distinguere i file di dispositivo, sono stati scelti in base a qualche criterio mnemonico e all'uso più frequente. Tuttavia non è detto che un dispositivo debba chiamarsi in un modo rispetto a un altro.

Sotto questo aspetto, le distribuzioni GNU/Linux non sono tutte uguali: ognuna interpreta in qualche modo questi nomi. Per fare un esempio, il dispositivo corrispondente all'unità a dischetti da 1 440 Kibyte, può corrispondere a questi nomi differenti:

Le cose si complicano ancora di più quando si ha a che fare con sistemi Unix differenti. Quindi: attenzione!

Le unità di memorizzazione di massa, ad accesso diretto,(3) sono dispositivi come gli altri, ma possono essere trattati in due modi diversi a seconda delle circostanze: possono essere viste come dei file enormi, oppure come contenitori di file (file system).

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 file unico. Il caso più comune è dato dai dischetti di avvio contenenti solo il kernel Linux: non si tratta di dischetti all'interno dei quali è stato copiato il file del kernel, ma si tratta di dischetti che sono il kernel.(4)

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

19.7   File e directory

Tutto ciò che è contenuto in un file system Unix è in forma di file: anche una directory è un 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 file normale, o regular file.

Una directory è un file speciale contenente riferimenti ad altri file. I dati contenuti in un file system sono organizzati in forma gerarchica schematizzabile attraverso un albero, ovvero un tipo particolare di grafo orientato che parte da una radice e si sviluppa in rami e nodi. La figura 19.4 mostra uno schema di un albero.

Figura 19.4. Albero.

Albero

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 idrogeno/carbonio/ossigeno rappresenta un attraversamento dei nodi idrogeno, carbonio e ossigeno.

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, /cloro/sodio indica un percorso assoluto che parte dalla radice per poi attraversare cloro e quindi raggiungere sodio.

Un albero è un grafo orientato, nel senso che i rami hanno una direzione (archi orientati), 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, ../potassio rappresenta un percorso relativo in cui si raggiunge il nodo finale, potassio, 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 punto singolo (.). Per cui, il percorso idrogeno/carbonio/ossigeno è esattamente uguale a ./idrogeno/carbonio/ossigeno.

19.7.1   Collegamenti

Un albero è tale purché esista uno e un solo percorso dalla radice a un qualunque altro nodo. Nei file system Unix non è necessariamente così; pertanto sono schematizzabili attraverso grafi orientati, ma non necessariamente degli alberi. Infatti è possibile inserire dei collegamenti aggiuntivi, o link, che permettono l'utilizzo di percorsi alternativi. Si distinguono due tipi di questi collegamenti: simbolici e fisici (hard).

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

19.7.2   Nomi dei file

Non esiste una regola generale precisa che stabilisca quali siano 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 cui si separano i nomi all'interno di un percorso; inoltre conviene limitarsi all'uso delle lettere dell'alfabeto inglese non accentate, dei numeri, del punto e del trattino basso.

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

I file che iniziano con un punto sono nascosti per una buona ragione: si vuole evitare che utilizzando i caratteri jolly si faccia riferimento alla directory stessa (.) e alla directory genitrice (..). Per tale ragione, si deve fare molta attenzione quando si 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 (a meno che il programma sia stato predisposto per evitare incidenti) elimina anche ., ma soprattutto .., cioè tutto il contenuto della directory genitrice!

19.7.3   Permessi

I file di un file system Unix appartengono simultaneamente a un utente e a un gruppo di utenti. Per questo si parla di utente e gruppo proprietari, oppure semplicemente di proprietario e di gruppo.

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 per gli utenti, a seconda che si tratti del proprietario del file, di utenti appartenenti al gruppo proprietario(5), oppure si tratti di utenti diversi. Così, per ogni file, un utente può ricadere in una di queste tre categorie: proprietario, gruppo o utente diverso.

I permessi si possono esprimere in due forme alternative: attraverso una stringa alfabetica oppure un numero.

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 di lettura, la lettera w indica un permesso di scrittura, la lettera x indica un permesso di esecuzione o di attraversamento.

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.

Figura 19.5. Associazione tra le classi di utenti e i permessi secondo lo schema tradizionale dei sistemi Unix.

collegamenti

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 quattro, il permesso di scrittura corrisponde al numero due, il permesso di esecuzione o attraversamento corrisponde al numero uno. Il numero che rappresenta il permesso attribuito a un tipo di utente, si ottiene sommando i numeri corrispondenti ai privilegi che si vogliono concedere.

Tabella 19.6. Esempi di rappresentazione di permessi.

Stringa Numero Descrizione
rw-r--r-- 644 L'utente proprietario può accedervi in lettura e scrittura (4+2), mentre sia gli appartenenti al gruppo, sia gli altri utenti, possono solo accedervi in lettura.
rwxr-x--- 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.
rw------- 600 L'utente proprietario può accedervi in lettura e scrittura (4+2), mentre tutti gli altri non possono accedervi affatto.

19.7.4   Permessi speciali: 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 altrettante modalità: SUID (Set user identifier), SGID (Set group identifier) e Sticky (Save text image). Si tratta di attributi speciali che riguardano prevalentemente i file eseguibili. Solitamente non vengono usati e per lo più gli utenti comuni ignorano che esistano.

Quanto descritto, serve in questa fase a conoscere il motivo per il quale spesso i permessi espressi in forma numerica (ottale) sono di quattro cifre, con la prima che normalmente è azzerata (l'argomento viene ripreso nel capitolo 175).

Per esempio, la modalità 0644 rappresenta il permesso per l'utente proprietario di accedervi in lettura e scrittura, mentre agli altri utenti si concede 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 di esecuzione. Nel caso in cui il permesso di esecuzione corrispondente non sia attivato, la lettera (s o t) appare maiuscola.

19.7.5   Date

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

19.8   Utenza e accesso

Una volta avviato un sistema Unix, prima che sia disponibile l'invito della shell, ovvero il prompt, occorre che l'utente sia riconosciuto dal sistema, attraverso la procedura di accesso (login). Quello che viene chiesto è l'inserimento del nome dell'utente (così come è stato registrato) e subito dopo la parola d'ordine (password) abbinata a quell'utente. Eccezionalmente può trattarsi di un utente senza parola d'ordine, 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 comuni. L'utente root non ha alcun limite di azione, gli altri utenti dipendono dai permessi attribuiti ai file (e alle directory) oltre che dai vincoli posti direttamente da alcuni programmi.

In teoria, è possibile usare un elaboratore 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 sulle directory, ma soprattutto si rendono vani i sistemi di sicurezza predefiniti contro gli errori. Chi ha usato un sistema Dos può comprendere meglio questo concetto se pensa a cosa succede quando si esegue un comando come quello seguente:

C:\> DEL *.*[Invio]

Prima di iniziare la cancellazione, il Dos chiede una conferma ulteriore, proprio perché non esiste alcun tipo di controllo. In un sistema Unix, di solito ciò non avviene: la cancellazione inizia immediatamente senza richiesta di conferme. Se i permessi consentono la cancellazione dei file solo all'utente 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, inoltre il sistema non pone alcuna obiezione al suo comportamento. Invece, un utente comune è vincolato dai permessi sui file e dai programmi che possono impedirgli di eseguire certe attività, di conseguenza, è possibile lavorare con meno attenzione.

19.8.1   Comandi «adduser» o «useradd»

Di solito, nelle distribuzioni GNU si trova il programma di servizio adduser, oppure useradd, che consente all'utente root di aggiungere un nuovo utente. Per rispettare la tradizione, il nome dell'utente di un sistema Unix non deve superare gli otto caratteri. In generale questa limitazione non sussiste nelle versioni recenti dei sistemi Unix; tanto meno nei sistemi GNU; tuttavia, alle volte si incontrano ancora vecchi programmi che hanno qualcosa a che fare con le utenze e possono risentire di questa limitazione.

Normalmente, quando si usano programmi come adduser, o useradd, di solito è sufficiente specificare il nominativo dell'utente che si crea, lasciando eventualmente tutti gli altri dati richiesti al loro valore predefinito. Dopo la prima installazione di un sistema Unix è importante creare il proprio utente personale per poter usare il sistema senza tutti i privilegi che ha l'amministratore.

19.8.2   Comando «exit»

La shell comprende solitamente il comando exit che ne termina l'esecuzione. Se si tratta di una shell avviata automaticamente subito dopo l'accesso, il sistema provvede poi ad avviare nuovamente la procedura di accesso.

19.9   Interpretazione dei comandi

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

19.9.1   File globbing

Il glob (o 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 a 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 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.

Dal momento che è la shell a eseguire la sostituzione dei caratteri jolly, la sintassi tipica di un programma di servizio è 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 per gli utilizzatori.

19.9.2   Tilde

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

19.9.3   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.

19.10   Ridirezione e condotti

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 è rappresentato di norma dai dati provenienti dalla tastiera del terminale. Lo standard output e lo standard error sono emessi normalmente attraverso lo schermo del terminale.

Per mezzo della shell si possono eseguire delle ridirezioni di questi flussi di dati, per esempio facendo in modo che lo standard output di un programma sia inserito come standard input di un altro, creando così un condotto (pipeline).

19.10.1   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.

L'esempio seguente visualizza il contenuto del file elenco.txt dopo averlo riordinato:

sort < elenco.txt[Invio]

19.10.2   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 maggiore per due volte di seguito: >>.

I due esempi seguenti mostrano la differenza nell'uso di > e di >>.

19.10.3   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>>.

I due esempi seguenti mostrano la differenza nell'uso di 2> e di 2>>.

19.10.4   Condotti

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 un condotto.

Segue la descrizione di alcuni esempi.

19.11   Comandi e programmi di servizio 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 semplicemente 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, con questo termine (comando) si fa spesso riferimento in maniera indistinta a comandi interni di shell o (in mancanza) a comandi esterni o programmi di servizio.

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

19.11.1   Interpretazione della sintassi

La sintassi per l'avvio di un programma o per l'esecuzione 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, osservando, se ci sono, gli esempi proposti.

19.11.2   Organizzazione tipica

Il programma di servizio tipico ha la sintassi seguente:

programma [opzioni] [file...]

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

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 oppure, spesso si possono raggruppare con un solo trattino seguito da tutte le lettere delle opzioni che si intendono selezionare. Quindi, spesso i due comandi seguenti sono equivalenti:

programma -a -b[Invio]

programma -ab[Invio]

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.

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

Alcuni programmi permettono l'utilizzo del trattino (-) in sostituzione dell'indicazione di file in ingresso o in uscita, allo scopo di fare riferimento, rispettivamente, allo standard input e allo standard output.

19.12   Programma o eseguibile

In generale, quando si usa il termine «programma» non si chiarisce quale sia la sua estensione reale. Si può usare questo termine per identificare qualcosa che si compone di un solo file eseguibile, oppure un piccolo sistema composto da più componenti, che vengono comandate da un solo sistema frontale.

Spesso, in particolare all'interno di questo documento, quando si vuole fare riferimento a un programma inteso come un insieme di componenti, oppure come qualcosa di astratto per il quale nel contesto non conta il modo in cui viene avviato, lo si indica con un nome che non ha enfatizzazioni particolari e generalmente ha l'iniziale maiuscola. Per esempio, questo è il caso della shell Bash, a cui si è accennato, il cui eseguibile è in realtà bash.

Per evitare ambiguità, quando si vuole essere certi di fare riferimento a un programma eseguibile, si specifica proprio che si tratta di questo, cioè di un «eseguibile», mostrandolo attraverso enfatizzazioni di tipo dattilografico, scrivendo il nome esattamente nel modo in cui ciò va fatto per avviarlo.

Appunti di informatica libera 2007.02 --- Copyright © 2000-2007 Daniele Giacomini -- <daniele (ad) swlibero·org>


1) La parola login va pronunciata separando le due sillabe: «log-in».

2) La sostituzione dei caratteri jolly, ovvero dei metacaratteri, è il procedimento attraverso il quale alcuni caratteri speciali vengono tradotti in un elenco di nomi di file e directory corrispondenti. Negli ambienti Unix si utilizza il termine globbing per fare riferimento a questo concetto.

3) Sono unità di memorizzazione di massa, per esempio, i dischi e le «memorie solide».

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

5) Per gruppo proprietario si intende quello che è stato attribuito ai file in questione.


Dovrebbe essere possibile fare riferimento a questa pagina anche con il nome introduzione_a_unix_e_ai_sistemi_gnu_in_particolare.htm

[successivo] [precedente] [inizio] [fine] [indice generale] [indice ridotto] [indice analitico]

Valid ISO-HTML!

CSS validator!