[inizio] [indice generale] [precedente] [successivo] [indice analitico] [contributi]


5. Esercizi pratici

GNU/Linux non è un sistema operativo «facile»; tuttavia, dovrebbe essere possibile trovare un amico o un conoscente in grado di dare una mano, e soprattutto di preparare un'installazione di questo sistema in modo da poter cominciare a fare un po' di pratica.

Questo capitolo raccoglie alcuni esercizi pratici che dovrebbero essere svolti da chi non ha esperienze con i sistemi operativi Unix e simili. Sono pensati per essere svolti su un elaboratore isolato, nel senso che non vengono trattate le funzionalità di rete.

Chi non ha quell'amico che può dare una mano, farebbe bene ugualmente a leggere questo capitolo anche se non può fare subito delle prove pratiche. Gli esempi sono mostrati in modo da essere abbastanza vicini all'interazione che avviene effettivamente tra l'utente e il sistema operativo.

5.1 Prerequisiti del sistema

Gli esercizi proposti assumono che il sistema GNU/Linux sia stato configurato nel modo seguente:

5.2 Accesso al sistema e conclusione dell'attività

Per utilizzare il sistema occorre accedere attraverso un processo di identificazione. Per poter essere identificati e accettati occorre essere stati registrati in un'utenza, rappresentata in pratica da un nominativo-utente e da una password. È importante rammentare che l'uso di lettere maiuscole o minuscole non è equivalente. Nell'esempio proposto si suppone di accedere utilizzando il nominativo `tizio', scritto così, con tutte le lettere minuscole, e la password `tazza'.

Si comincia dall'inserimento del nominativo, volontariamente errato.

login: tizia[Invio]

Anche se il nominativo indicato non esiste, viene richiesto ugualmente l'inserimento della password. Si tratta di una misura di sicurezza, per non dare informazioni sull'esistenza o meno di un determinato nominativo-utente.

Password: tazza[Invio]

Login incorrect

Naturalmente, l'inserimento della parola `tazza', in qualità di password, avviene alla cieca, nel senso che non appare come sembrerebbe dall'esempio. Ciò serve a evitare che un vicino indiscreto possa in seguito utilizzare tale informazione per scopi spiacevoli.

Se si sbaglia qualcosa nella fase di accesso (login), si deve ricominciare. Questa volta si suppone di eseguire l'operazione in modo corretto.

login: tizio[Invio]

Password: tazza[Invio]

Last login: Sun Nov 11 10:45:11 on tty1

Generalmente, dopo avere superato correttamente la procedura di accesso, si ottiene l'informazione sull'ultima volta che quell'utente ha fatto un accesso. Ciò permette di verificare in maniera molto semplice che nessuno abbia utilizzato il sistema accedendo con il proprio nominativo.

Successivamente si ottiene l'invito della shell (il prompt) che sta a indicare la sua disponibilità a ricevere dei comandi.

$

L'invito, rappresentato in questo esempio da un simbolo dollaro, può essere più o meno raffinato, con l'indicazione di informazioni ritenute importanti dall'utente. Infatti si tratta di qualcosa che ogni utente può configurare come vuole, ma questo va oltre lo scopo di queste esercitazioni.

Spesso, per tradizione, l'invito termina con un simbolo che cambia in funzione del livello di importanza dell'utente: se si tratta di `root' si usa il simbolo `#', altrimenti il dollaro, come in questo esempio.

5.2.1 Cambiamento di identità

Quando la stessa persona dispone di più di un'utenza, può essere opportuno, o necessario, agire sotto una diversa identità rispetto a quella con cui si accede attualmente. Questa è la situazione tipica in cui si trova l'amministratore di un sistema: per le operazioni diverse dall'amministrazione vera e propria dovrebbe accedere in qualità di utente comune, mentre negli altri casi deve utilizzare i privilegi riservati all'utente `root'.

Ci sono due modi fondamentali: concludere la sessione di lavoro e accedere con un altro nominativo-utente, oppure utilizzare il comando `su' in modo da cambiare temporaneamente i propri privilegi.

su caio[Invio]

Password: ciao[Invio]

Se la password è corretta si ottengono i privilegi e l'identità dell'utente indicato, altrimenti tutto resta come prima.

5.2.2 Console virtuali

Un sistema GNU/Linux, installato in modo normale, consente l'utilizzo di diverse console virtuali (di solito sono sei) a cui si accede con la combinazione [Alt+Fn] (dove n è un numero da uno a sei).

Quando è già stato fatto un accesso, si può iniziare un'altra sessione di lavoro in un'altra console.

[Alt+F2]

In questo modo si passa alla seconda console virtuale e su questa si può eseguire un accesso differente. Le attività svolte nelle varie console virtuali sono indipendenti, come se avvenissero attraverso terminali fisicamente distinti.

Prima di proseguire con gli esercizi si deve ritornare alla console virtuale utilizzata in precedenza.

[Alt+F1]

5.2.3 Chi sono?

Quando la stessa persona può accedere utilizzando diversi nominativi-utente, potrebbe essere necessario controllare con quale identità sta operando. Negli esempi che seguono si suppone che si sia riusciti a eseguire il comando `su caio' mostrato in precedenza.

whoami[Invio]

caio

Il comando `whoami' («chi sono») permette di conoscere con quale identità si sta operando.

logname[Invio]

tizio

Il comando `logname' permette di conoscere con quale identità ci si è presentati inizialmente, nel momento dell'accesso.

5.2.4 Terminare una sessione di lavoro

Per terminare una sessione di lavoro è sufficiente concludere l'attività della shell, ovvero di quel programma che mostra l'invito.

Se la situazione è quella degli esempi precedenti, si stava operando come utente `caio' dopo un comando `su', mentre prima di questo si stava usando l'identità dell'utente `tizio'.

whoami[Invio]

caio

exit[Invio]

In tal caso, il comando `exit' appena eseguito fa tornare semplicemente alla situazione precedente all'esecuzione di `su'

whoami[Invio]

tizio

Il comando `exit' che chiude l'ultima shell, termina l'accesso al sistema.

exit[Invio]

login:

Si ripresenta la richiesta di identificazione della procedura di accesso.

5.2.5 Spegnimento

Lo spegnimento dell'elaboratore può avvenire solo dopo che il sistema è stato fermato, generalmente attraverso il comando `shutdown' che però è accessibile solo all'utente `root'.

login: root[Invio]

Password: ameba[Invio]

shutdown -h now[Invio]

System is going down NOW!!
...

Inizia la procedura di arresto del sistema, che si occupa di eliminare gradualmente tutti i servizi attivi. Infine viene visualizzato il messaggio

System halted

oppure

Power down

a seconda della versione del kernel. Quando questo appare è possibile spegnere o riavviare l'elaboratore.

---------

Se si vuole utilizzare `shutdown' attraverso il comando `su' in modo da non dovere uscire e rifare un login, è possibile agire come di seguito.

su[Invio]

Quando si utilizza il comando `su' senza argomenti si indica implicitamente che si vuole ottenere l'identità dell'utente `root'.

Password: ameba[Invio]

shutdown -h now[Invio]

5.2.6 Conclusione

Il meccanismo attraverso cui si accede al sistema deve essere chiaro, prima di poter affrontare qualunque altra cosa. Prima di proseguire occorre essere certi che gli esempi visti fino a questo punto siano stati compresi, soprattutto, in seguito non verrà più mostrato il modo con cui accedere, terminare una sessione di lavoro o cambiare identità.

È fondamentale tenere bene a mente che l'elaboratore non può essere spento prima di avere completato la procedura di arresto del sistema con `shutdown'.

In caso di dubbio è meglio ripetere l'esercitazione precedente.

5.3 Gestione delle password

La prima regola per una password sicura consiste nel suo aggiornamento frequente. Quando si cambia la password, viene richiesto inizialmente l'inserimento della password precedente, quindi si può inserire quella nuova, per due volte, in modo da prevenire eventuali errori di battitura. Non vengono accettate le password troppo semplici (solo l'utente `root' ha la possibilità di assegnare password banali).

5.3.1 L'utente root che cambia la password di un utente comune

L'utente `root' può cambiare la password di un altro utente. Questa è la situazione comune di quando si crea una nuova utenza: è l'utente `root' che assegna la prima volta la password per quel nuovo utente.

passwd tizio[Invio]

Trattandosi dell'utente `root' che cambia la password di un altro, viene richiesto semplicemente di inserire quella nuova (l'utente `root' non ha la necessità di conoscere la vecchia password di un altro utente).

New UNIX password: 123[Invio]

La password inserita (che nella realtà non si vede) è troppo breve e anche banale. Il programma avverte di questo, ma non si oppone.

BAD PASSWORD: it's a WAY too short

Retype new UNIX password: 123[Invio]

passwd: all authentication tokens updated successfully

La password è stata cambiata.

5.3.2 L'utente comune che cambia la propria password

L'utente comune può cambiare la propria password, solo la propria, e a lui non è consentito di assegnarsi una chiave di accesso troppo semplice. Nell'esempio, l'utente è `tizio'.

passwd[Invio]

Prima di accettare una nuova password, viene richiesta quella vecchia.

Changing password for tizio

(current) UNIX password: 123[Invio]

Quindi viene richiesta quella nuova.

New UNIX password: albero[Invio]

BAD PASSWORD: it is based on a (reversed) dictionary word
passwd: Authentication token manipulation error

Come si vede, la password `albero' viene considerata troppo semplice e il programma si rifiuta di procedere. Si decide allora di usare qualcosa di più complesso, o semplicemente più lungo.

passwd[Invio]

Changing password for tizio

(current) UNIX password: 123[Invio]

New UNIX password: fra martino campanaro[Invio]

Si è optato per una password lunga. Occorre tenere a mente che conta la differenza tra maiuscole e minuscole e anche il numero esatto di spazi inseriti tra le parole.

Retype new UNIX password: fra martino campanaro[Invio]

passwd: all authentication tokens updated successfully

A seconda della configurazione del sistema, e dell'aggiornamento delle librerie, può darsi che sia perfettamente inutile utilizzare delle password più lunghe di otto caratteri, nel senso che ciò che eccede i primi otto caratteri potrebbe essere semplicemente ignorato. Si può provare a verificarlo; seguendo l'esempio appena visto, potrebbe essere che la password risultante sia solo `fra mart'.

5.3.3 Conclusione

Il cambiamento della password in un sistema GNU/Linux, e in generale in un sistema Unix, deve essere considerato una cosa abituale, anche per gli utenti comuni. Le password troppo semplici non sono accettabili.

5.4 Navigazione tra le directory

I dati contenuti in un filesystem sono organizzati in modo gerarchico attraverso directory e sottodirectory. Prima di iniziare questa esercitazione è conveniente rivedere la sezione 4.7.

L'utente a cui ci si riferisce negli esempi è `tizio'.

5.4.1 Directory corrente

Mentre si utilizza il sistema, i comandi che si eseguono risentono generalmente della posizione corrente in cui ci si trova, ovvero della directory attuale, o attiva. Tecnicamente non c'è bisogno di definire una directory corrente: tutte le posizioni nell'albero del filesystem potrebbero essere indicate in maniera precisa. In pratica, la presenza di questa directory corrente semplifica molte cose.

cd /usr/bin[Invio]

Eseguendo il comando precedente, la directory attuale dovrebbe divenire `/usr/bin/'. Per controllare che ciò sia avvenuto si utilizza il comando seguente:

pwd[Invio]

/usr/bin

5.4.2 Spostamenti assoluti e relativi

Il comando `cd' può essere utilizzato per cambiare la directory corrente, sia attraverso l'indicazione di un percorso assoluto, sia attraverso un percorso relativo. Il percorso assoluto parte dalla directory radice, mentre quello relativo parte dalla posizione corrente.

cd /usr/local[Invio]

Il comando soprastante cambia la directory corrente in modo che diventi esattamente `/usr/local/'. Il percorso indicato è assoluto perché inizia con una barra obliqua che rappresenta la directory radice.

pwd[Invio]

/usr/local

Quando si utilizza l'indicazione di un percorso che non inizia con una barra obliqua, si fa riferimento a qualcosa che inizia dalla posizione corrente.

cd bin[Invio]

Con questo comando si cambia la directory corrente, passando in `bin/' che discende da quella attuale.

pwd[Invio]

/usr/local/bin

5.4.3 Spostamenti a ritroso

Ogni directory contiene due riferimenti convenzionali a due sottodirectory speciali. Si tratta del riferimento alla directory corrente rappresentato da un punto singolo (`.') e del riferimento alla directory precedente, rappresentato da due punti in sequenza (`..'). Questi simboli (il punto singolo e quello doppio) sono nomi di directory a tutti gli effetti.

cd ..[Invio]

Cambia la directory corrente tornando a quella precedente. Si tratta di un percorso relativo che utilizza, come punto di inizio, la directory corrente del momento in cui si esegue il comando.

pwd[Invio]

/usr/local

Gli spostamenti relativi che fanno uso di un movimento all'indietro possono essere più elaborati.

cd ../bin[Invio]

In questo caso si intende indietreggiare di una posizione e quindi entrare nella directory `bin/'.

pwd[Invio]

/usr/bin

Lo spostamento a ritroso può essere anche cumulato a più livelli.

cd ../../var/tmp[Invio]

In questo caso si indietreggia due volte prima di riprendere un movimento in avanti.

pwd[Invio]

/var/tmp

Gli spostamenti all'indietro si possono usare anche in modo più strano e apparentemente inutile.

cd /usr/bin/../local/bin/..[Invio]

Indubbiamente si tratta di un'indicazione poco sensata, ma serve a comprendere le possibilità date dall'uso del riferimento alla directory precedente.

pwd[Invio]

/usr/local

5.4.4 Riferimento preciso alla directory corrente

La directory corrente può essere rappresentata da un punto singolo. In pratica, tutti i percorsi relativi potrebbero iniziare con il prefisso `./' (punto, barra obliqua). Per quanto riguarda lo spostamento all'interno delle directory, ciò serve a poco, ma ritorna utile in altre situazioni.

cd ./bin[Invio]

A partire dalla directory corrente si sposta nella directory `bin/'.

pwd[Invio]

/usr/local/bin

5.4.5 Directory personale, o directory home

Ogni utente ha una directory personale, detta anche directory home, ed è quella destinata a contenere tutto ciò che riguarda l'utente a cui appartiene. Usando il comando `cd' senza argomenti, si raggiunge la propria directory personale, senza bisogno di indicarla in modo preciso.

cd[Invio]

pwd[Invio]

/home/tizio

Alcune shell sostituiscono il carattere tilde (`~'), all'inizio di un percorso, con la directory personale dell'utente che lo utilizza.

cd ~[Invio]

pwd[Invio]

/home/tizio

Nello stesso modo, un nominativo-utente preceduto da un carattere tilde, viene sostituito dalla directory personale dell'utente stesso. *1*

cd ~caio[Invio]

pwd[Invio]

/home/caio

Prima di proseguire si ritorna nella propria directory personale.

cd[Invio]

5.4.6 Conclusione

La directory corrente è un punto di riferimento importante per i programmi, e il cambiamento di questa posizione avviene attraverso il comando `cd'. Per conoscere quale sia la directory corrente si utilizza `pwd'. La directory precedente a quella attuale si rappresenta con una sequenza di due punti (`..') mentre quella attuale si può indicare con un punto singolo (`.').

5.5 Contenuti

La navigazione all'interno delle directory, alla cieca, come visto negli esempi dell'esercitazione precedente, è una cosa possibile ma insolita: normalmente si accompagna con l'analisi dei contenuti di directory e file.

5.5.1 Contenuto delle directory

Le directory si esplorano con il comando `ls'

ls /bin[Invio]

arch           dd             gzip           nisdomainname  tar
ash            df             hostname       ping           touch
awk            dmesg          kill           ps             true
basename       dnsdomainname  ln             pwd            umount
bash           doexec         login          rm             uname
bsh            domainname     ls             rmdir          vi
cat            echo           mail           rpm            view
chgrp          egrep          mkdir          sed            vim
chmod          ex             mknod          sh             ypdomainname
chown          false          more           sleep          zcat
cp             fgrep          mount          sort
cpio           gawk           mt             stty
csh            grep           mv             su
date           gunzip         netstat        sync

Il comando `ls /bin' visualizza il contenuto della directory `/bin/'. I nomi che vengono elencati rappresentano file di qualunque tipo (sottodirectory incluse).

Una visualizzazione più espressiva del contenuto delle directory può essere ottenuta utilizzando l'opzione `-l'.

ls -l /bin[Invio]

-rwxr-xr-x   1 root     root         2712 Jul 20 03:15 arch
-rwxrwxrwx   1 root     root        56380 Apr 16  1997 ash
lrwxrwxrwx   1 root     root            4 Oct 21 11:15 awk -> gawk
-rwxr-xr-x   1 root     root        18768 Apr 18  1997 basename
-rwxrwxrwx   1 root     root       412516 Jul 17 21:27 bash
lrwxrwxrwx   1 root     root            3 Oct 21 11:15 bsh -> ash
-rwxr-xr-x   1 root     root        22164 Mar 14  1997 cat
-rwxr-xr-x   1 root     root        23644 Feb 25  1997 chgrp
-rwxr-xr-x   1 root     root        23960 Feb 25  1997 chmod
-rwxr-xr-x   1 root     root        23252 Feb 25  1997 chown
-rwxr-xr-x   1 root     root        61600 Feb 25  1997 cp
-rwxr-xr-x   1 root     root       296728 Apr 23  1997 cpio
...

In questo caso, si è ottenuto un elenco più dettagliato che in particolare consente di distinguere il tipo di file, i permessi e l'appartenenza all'utente e al gruppo.

In precedenza è stato spiegato che ogni directory contiene due riferimenti convenzionali rappresentati da un punto singolo e da due punti in sequenza (`.' e `..'). Negli esempi appena visti, questi non sono apparsi. Ciò accade perché i file il cui nome inizia con un punto non vengono presi in considerazione quando non si fa riferimento a loro in modo preciso.

cd[Invio]

ls[Invio]

La directory personale di un utente potrebbe sembrare vuota, utilizzando il comando `ls' appena visto. Con l'opzione `-a' si visualizzano anche i file che iniziano con un punto (si osservi che in precedenza non apparivano i riferimenti alle voci `.' e `..').

ls -a[Invio]

.                .bash_profile    .riciclaggio
..               .bashrc          .screenrc
.Xdefaults       .fvwm2rc95       .twmrc
.bash_history    .mc.ext          .xfm
.bash_logout     .mc.ini          .xinitrc

5.5.2 Contenuto dei file

Anche il contenuto dei file può essere analizzato, entro certi limiti, soprattutto quando si tratta di file di testo. Per visualizzare il contenuto di file di testo si utilizzano generalmente i comandi `cat' e `more'.

cat /etc/fstab[Invio]

/dev/hda3	/		ext2		defaults	1  1
/dev/hda2	none		swap		sw
proc		/proc		ignore
/dev/hda1	dos		vfat		quiet,umask=000
/dev/hdc	/mnt/cdrom	iso9660		ro,user,noauto
/dev/fd0	/mnt/floppy	vfat		user,noauto,quiet

Con il comando appena indicato si è ottenuta la visualizzazione del contenuto del file `/etc/fstab', che ovviamente cambia a seconda della configurazione del proprio sistema.

`cat', usato così, non si presta alla visualizzazione di file di grandi dimensioni. Per questo si preferisce usare `more', oppure il più raffinato `less'. Questi programmi sono descritti nella sezione 18.1.

5.5.3 Determinazione del tipo

Il contenuto dei file può essere determinato attraverso il comando `file', senza doverne visualizzare il contenuto. Ciò è molto importante, specialmente nelle situazioni in cui visualizzare un file è inopportuno (si pensi a cosa accadrebbe tentando di visualizzare un file eseguibile binario).

Il comando `file' si basa su una serie di stringhe di riconoscimento chiamate magic number (una sorta di «impronta»), definite in base alla tradizione dei sistemi Unix.

file /etc/*[Invio]

/etc/DIR_COLORS:       English text
/etc/HOSTNAME:         ASCII text
/etc/X11:              directory
/etc/adjtime:          ASCII text
/etc/aliases:          English text
/etc/aliases.db:       Berkeley DB Hash file (Version 2, Little Endian,...
/etc/at.deny:          ASCII text
/etc/bashrc:           ASCII text
/etc/cron.daily:       directory
/etc/cron.hourly:      directory
/etc/cron.monthly:     directory
/etc/cron.weekly:      directory
/etc/crontab:          ASCII text
/etc/csh.cshrc:        ASCII text
/etc/dosemu.conf:      English text
/etc/dosemu.users:     ASCII text
...

Il comando indicato come esempio visualizza l'elenco dei file contenuti nella directory `/etc/', e a fianco di ogni file appare la definizione del tipo a cui questo appartiene.

Questo metodo di riconoscimento dei dati non è infallibile, ma è comunque di grande aiuto.

5.5.4 Spazio utilizzato e spazio disponibile

Per controllare lo spazio disponibile nel disco (o nei dischi) si utilizza il comando `df'.

df[Invio]

Il risultato del comando potrebbe essere qualcosa di simile a quanto segue.

Filesystem         1024-blocks  Used Available Capacity Mounted on
/dev/hda4             648331  521981    92860     85%   /
/dev/hda1              41024   38712     2312     94%   /dos

Per controllare lo spazio utilizzato in una directory si può utilizzare il comando `du'.

du /bin[Invio]

3168	/bin

In questo caso, si determina che la directory `/bin/' contiene file per un totale di 3168 Kbyte.

5.5.5 Conclusione

L'analisi del contenuto di directory e file è un'operazione elementare, ma essenziale per la determinazione delle azioni da compiere in funzione di quanto si rivela in questo modo.

5.6 Creazione, copia ed eliminazione di file

La creazione, la copia, e l'eliminazione dei file sono operazioni elementari, ma importanti e delicate. Questa esercitazione deve essere fatta con cura e attenzione.

5.6.1 Creazione di un file

Esistono vari modi per creare un file. Il modo più semplice per creare un file vuoto è quello di usare il comando `touch'. Prima di tutto ci si sposta nella propria directory personale, che è il luogo più adatto per questo genere di esercizi.

cd[Invio]

touch pippo[Invio]

Dopo aver usato il comando `touch' per creare il file `pippo' non si ottiene alcuna conferma dell'avvenuta esecuzione dell'operazione. Questo atteggiamento è tipico dei sistemi Unix i cui comandi tendono a non manifestare il successo delle operazioni eseguite. Si può comunque verificare.

ls -l pippo[Invio]

-rw-rw-r--   1 tizio    tizio           0 Dec 23 10:49 pippo

Il file è stato creato.

In questa fase degli esercizi, in cui non è ancora stato descritto l'uso di un programma per creare o modificare file di testo, è possibile vedere un metodo semplice per creare un file del genere. Si utilizza il comando `cat' in un modo un po' strano che verrà chiarito più avanti.

cat > pippo2[Invio]

Da questo momento inizia l'inserimento del testo come nell'esempio mostrato qui di seguito.

Esiste anche un modo semplice di scrivere[Invio]

un file di testo.[Invio]

Purtroppo si tratta di una scrittura a senso unico.[Invio]

[Ctrl+d]

L'inserimento del testo termina con la combinazione [Ctrl+d].

Si può verificare che il file sia stato creato e contenga il testo digitato.

cat pippo2[Invio]

Esiste anche un modo semplice di scrivere
un file di testo.
Purtroppo si tratta di una scrittura a senso unico.

5.6.2 Copia di file

La copia dei file può essere fatta attraverso l'uso del comando `cp'.

cp pippo2 pippo3[Invio]

Eseguendo il comando appena mostrato, si ottiene la copia del file `pippo2' per generare il file `pippo3'. Come al solito, se tutto va bene, non si ottiene alcuna segnalazione.

La copia di un gruppo di file può avvenire solo quando la destinazione (l'ultimo nome indicato nella riga di comando) è una directory già esistente.

cp pippo pippo2 pippo3 /tmp[Invio]

Con il comando precedente si copiano i file creati fino a questo punto nella directory `/tmp/'. La stessa cosa si può fare in modo più semplice utilizzando i caratteri jolly.

cp pippo* /tmp[Invio]

5.6.3 Eliminazione di file

L'eliminazione dei file avviene normalmente per mezzo di `rm'. L'uso di questo comando deve essere fatto con molta attenzione, specialmente quando si agisce con i privilegi dell'utente `root'. Infatti, la cancellazione avviene senza obiezioni e senza richiedere conferme. Può bastare un errore banale per cancellare tutto ciò a cui si può accedere.

rm pippo pippo2[Invio]

Il comando appena mostrato elimina definitivamente e senza possibilità di recupero i file indicati: `pippo' e `pippo2'.

La cancellazione dei file può avvenire anche indicandone un gruppo attraverso l'uso dei caratteri jolly. L'uso di questi simboli rappresenta un rischio in più. Generalmente, quando non si ha ancora una buona preparazione e si può essere incerti sull'effetto di un comando di eliminazione, conviene prima controllare il risultato, per esempio attraverso `ls'. *2*

Volendo cancellare tutti i file il cui nome inizia per `pippo', si potrebbe utilizzare il modello `pippo*'. Per sicurezza si verifica con `ls'.

ls pippo*[Invio]

pippo3

Risulta corrispondere al modello solo il file `pippo3'. Infatti, poco prima erano stati cancellati `pippo' e `pippo2'. In ogni caso, si vede che il modello è corretto e si procede con la cancellazione (tuttavia si deve fare attenzione ugualmente).

rm pippo*[Invio]

L'uso distratto di questo comando di eliminazione, può produrre danni, anche gravi. Si pensi a cosa può accadere se, invece di digitare `rm pippo*' si inserisse accidentalmente uno spazio tra la parola `pippo' e l'asterisco. Il comando sarebbe `rm pippo *' e produrrebbe l'eliminazione del file `pippo' (se esiste) e successivamente l'eliminazione di tutti i file contenuti nella directory corrente (questo è ciò che rappresenta l'asterisco da solo). Come è già stato spiegato, `rm' non fa domande, così come accade con gli altri comandi, nel rispetto delle tradizioni Unix: quello che è cancellato è cancellato.

5.6.4 Conclusione

La creazione di file, normalmente vuoti, la copia e l'eliminazione, sono operazioni elementari ma fondamentali. Nella loro semplicità si tratta comunque di funzionalità che richiedono un po' di attenzione, soprattutto quando si interviene con i privilegi dell'utente `root': con la copia si potrebbero sovrascrivere file già esistenti, con la cancellazione si potrebbe intervenire in un ambito diverso da quello previsto o desiderato.

5.7 Creazione, copia ed eliminazione di directory

Le directory possono essere viste come contenitori di file e di altre directory. La copia e l'eliminazione di directory ha delle implicazioni differenti rispetto alle stesse operazioni con i file normali. Continua a valere la raccomandazione di svolgere l'esercitazione con cura.

5.7.1 Creazione di una directory

La creazione di una directory è concettualmente simile alla creazione di un file vuoto. Quando la directory viene creata è sempre vuota: si riempirà utilizzandola. Una directory viene creata con il comando `mkdir'.

Prima di procedere ci si sposta nella propria directory personale e quindi si crea la directory `mia/' discendente dalla posizione corrente.

cd[Invio]

mkdir mia[Invio]

Si può verificare con il comando `ls'.

ls -l[Invio]

...
drwxr-xr-x   8 tizio    tizio        1024 Dec 23 12:11 mia
...

La lettera `d' all'inizio della stringa che identifica i permessi indica chiaramente che si tratta di una directory.

5.7.2 Copia di directory

La copia delle directory avviene attraverso il comando `cp' con le opzioni `-r' oppure `-R', tra le quali c'è una differenza sottile che però qui non verrà approfondita.

cp -r mia mia2[Invio]

Con il comando appena visto, si ottiene la copia della directory `mia/' in `mia2/'. La copia è ricorsiva, nel senso che comprende tutti i file contenuti nella directory di origine, e anche tutte le eventuali sottodirectory (e con loro tutti i file contenuti in queste sottodirectory eventuali...).

5.7.3 Eliminazione di directory

Normalmente, le directory si possono cancellare quando sono vuote, e questo per mezzo del comando `rmdir'.

Valgono le stesse raccomandazioni di prudenza fatte in precedenza in occasione degli esercizi sulla cancellazione di file.

rmdir mia2[Invio]

Il comando appena mostrato elimina la directory `mia2/'.

L'eliminazione delle directory fatta in questo modo, cioè attraverso il comando `rmdir', non è molto preoccupante, perché con esso è consentito eliminare solo directory vuote: se ci si accorge di avere eliminato una directory di troppo, si riesce facilmente a ricrearla con il comando `mkdir'.

Tuttavia, spesso si eliminano interi rami di directory, quando con un comando si vuole eliminare una o più directory, e con esse il loro contenuto di file ed eventuali altre directory. Si dice in questo caso che si esegue una cancellazione ricorsiva.

Prima di proseguire, si prova a creare una struttura articolata di directory.

mkdir carbonio[Invio]

mkdir carbonio/idrogeno[Invio]

mkdir carbonio/ossigeno[Invio]

mkdir carbonio/idrogeno/elio[Invio]

Si dovrebbe ottenere una struttura organizzata nel modo seguente:

tree carbonio[Invio]

carbonio
|-- idrogeno
|   `-- elio
`-- ossigeno

3 directories, 0 files

Se si tenta di eliminare tutta la struttura che parte da `carbonio/' con il comando `rmdir', si ottiene solo una segnalazione di errore.

rmdir carbonio[Invio]

rmdir: carbonio: Directory not empty

Per questo bisogna utilizzare il comando `rm' con l'opzione `-r'. Tuttavia, il comando `rm' usato in questo modo ricorsivo è particolarmente pericoloso se utilizzato in modo distratto.

rm -r carbonio[Invio]

La directory `carbonio/' e tutto ciò che da essa discendeva non c'è più.

Si provi a pensare cosa può accadere quando si utilizzano i caratteri jolly: si cancellano indifferentemente file e directory che corrispondono al modello. C'è però ancora qualcosa di peggiore: l'insidia dei nomi che iniziano con un punto.

5.7.4 Eliminazione di directory il cui nome inizia con un punto

La cancellazione di directory il cui nome inizia con un punto è un'operazione estremamente delicata che merita una discussione a parte. Generalmente, quando si utilizzano i caratteri jolly per identificare un gruppo di nomi di file e directory, questi simboli non corrispondono mai ai nomi che iniziano con un punto. Questa convenzione è stata definita per evitare che con i caratteri jolly si possa intervenire involontariamente con i riferimenti standard delle directory: `.' (la directory corrente) e `..' (la directory precedente).

A questo fatto si è aggiunta la convenzione di nominare in questo modo (con un punto iniziale) file e directory che rappresentano la configurazione particolare di ogni utente. In tal modo, è come se tali file e directory fossero nascosti, e l'utente non risulta infastidito da questi che così non possono nemmeno essere cancellati involontariamente.

Potrebbe sorgere il desiderio di eliminare tutti questi file e tutte queste directory, utilizzando il modello `.*' (punto, asterisco), ma in questo modo si eliminerebbero anche i riferimenti standard: `.' e `..', eliminando così anche la directory corrente e quella precedente.

Ma se tutto questo avviene in modo ricorsivo, con l'opzione `-r', è come ordinare di cancellare tutto il filesystem.

Se il comando viene dato da un utente comune, questo riuscirà a eliminare solo i dati a cui può accedere, mentre se questo sbaglio viene fatto dall'utente `root', il disastro è totale.

Per concludere, il comando incriminato è `rm -r .*'. Siete stati avvisati!

5.7.5 Conclusione

Quando si copiano e si eliminano le directory sorge spontaneo il desiderio di intervenire in modo ricorsivo su tutto il contenuto della directory di partenza. I problemi maggiori cui si va incontro sono legati alla cancellazione ricorsiva, specialmente quando si pretende di eliminare i file e le directory il cui nome inizia con un punto, in modo globale, attraverso un modello fatto di caratteri jolly.

5.8 Spostamenti e collegamenti di file e directory

Negli ambienti Unix, lo spostamento e il cambiamento di nome di file e directory sono la stessa cosa. Un'altra particolarità dei sistemi operativi Unix è la possibilità di gestire i collegamenti a file e directory.

5.8.1 Spostamento e ridenominazione

Lo spostamento di file e directory avviene per mezzo di `mv'. Per esercitarsi con questo comando si preparano alcuni file e alcune directory.

touch alfa[Invio]

touch beta[Invio]

mkdir gamma[Invio]

Come sempre è bene controllare.

ls -l[Invio]

...
-rw-rw-r--   1 tizio    tizio           0 Dec 25 12:46 alfa
-rw-rw-r--   1 tizio    tizio           0 Dec 25 12:46 beta
drwxrwxr-x   2 tizio    tizio        1024 Dec 25 12:46 gamma
...

Si procede rinominando il file `alfa' in modo che diventi `omega'.

mv alfa omega[Invio]

ls -l[Invio]

...
-rw-rw-r--   1 tizio    tizio           0 Dec 25 12:46 omega
...

Volendo spostare una serie di file e directory in gruppo, è necessario che la destinazione sia una directory. Con il comando seguente si spostano i due file creati poco prima nella directory `gamma/'.

mv omega beta gamma[Invio]

ls -l gamma[Invio]

-rw-rw-r--   1 tizio    tizio           0 Dec 25 12:46 beta
-rw-rw-r--   1 tizio    tizio           0 Dec 25 12:46 omega

Generalmente, lo spostamento (o il cambiamento di nome) non fa differenza tra file normali e directory.

mv gamma /tmp[Invio]

Il comando precedente sposta la directory `gamma/' in `/tmp/'.

È importante tenere presente che il comando `mv' non può cambiare una serie di nomi in modo sistematico. Per esempio, non si può cambiare `*.mio' in `*.tuo'.

5.8.2 Collegamenti

La creazione di un collegamento è un'operazione simile alla copia, con la differenza che invece di creare un duplicato di file e directory, si genera un riferimento agli originali. Ne esistono due tipi: collegamenti simbolici e collegamenti fisici (questi ultimi conosciuti di solito come hard link). In questa esercitazione verranno mostrati solo collegamenti simbolici.

Il comando utilizzato per creare questi collegamenti è `ln'; dal momento che si intendono mostrare solo quelli simbolici, si userà sempre l'opzione `-s'.

Per esercitarsi con questo comando si preparano alcuni file e directory.

touch uno[Invio]

touch due[Invio]

mkdir tre[Invio]

Come sempre è bene controllare.

ls -l[Invio]

...
-rw-rw-r--   1 tizio    tizio           0 Dec 25 12:46 due
drwxrwxr-x   2 tizio    tizio        1024 Dec 25 12:46 tre
-rw-rw-r--   1 tizio    tizio           0 Dec 25 12:46 uno

Come si accennava all'inizio, la creazione di un collegamento è un'operazione simile alla copia.

ln -s uno uno.bis[Invio]

Con il comando mostrato sopra, si ottiene un collegamento simbolico, denominato `uno.bis', al file `uno'.

ls -l[Invio]

...
lrwxrwxrwx   1 tizio    tizio           3 Dec 25 12:47 uno.bis -> uno

Da questo momento si può fare riferimento al file `uno' utilizzando il nome `uno.bis'.

La creazione di un collegamento a una directory può avvenire nello stesso modo visto per i file (a patto che si tratti di collegamenti simbolici).

ln -s /tmp miatemp[Invio]

Se il comando appena visto ha successo si può raggiungere la directory `/tmp/' anche attraverso il riferimento `miatemp'.

La creazione di un gruppo di collegamenti con un solo comando, può avvenire solo quando la destinazione (l'ultimo nome sulla riga di comando) è una directory. In questo modo si ottiene la creazione di una serie di collegamenti al suo interno.

ln -s /home/tizio/uno* /home/tizio/due tre[Invio]

In questo caso, si generano una serie di collegamenti per tutti i file i cui nomi iniziano per `uno' e anche per il file `due' nella directory `tre/'.

Nell'esempio mostrato sopra, i file per i quali si vogliono creare dei collegamenti simbolici sono stati indicati con il loro percorso assoluto, pur immaginando che la directory `/home/tizio/' fosse quella corrente. In tal senso, la directory di destinazione è stata indicata semplicemente in modo relativo. Quando si creano una serie di collegamenti in una directory come in questo modo, è necessario indicare anche il percorso nei file (o nelle directory) di origine.

ls -l tre[Invio]

lrwxrwxrwx   1 tizio    tizio    15 Dec 25 15:21 due -> /home/tizio/due
lrwxrwxrwx   1 tizio    tizio    15 Dec 25 15:21 uno -> /home/tizio/uno
lrwxrwxrwx   1 tizio    tizio    19 Dec 25 15:21 uno.bis -> /home/tizio/uno.bis

Si può osservare che è stato creato anche un collegamento che punta a un altro collegamento.

5.8.3 Conclusione

Lo spostamento di file e directory avviene in modo simile alla copia, solo che l'origine viene rimossa. Lo spostamento di directory attraverso unità di memorizzazione differenti non è possibile. Lo spostamento erroneo può essere dannoso: se non si fa attenzione si può sovrascrivere qualcosa che ha già lo stesso nome dei file o delle directory di destinazione. Questo è lo stesso tipo di problema che si rischia di incontrare con la copia.

I collegamenti a file e directory permettono di definire percorsi alternativi agli stessi.

5.9 La shell

La shell è il mezzo attraverso cui si interagisce con il sistema. Il modo di inserire i comandi può cambiare molto da una shell all'altra. Gli esercizi proposti in questa sezione sono fatti in particolare per la shell Bash, ma gran parte di questi possono essere validi anche per altre shell.

5.9.1 Completamento automatico

Il completamento automatico è un modo attraverso cui la shell aiuta l'utente a completare un comando. La richiesta di completamento viene fatta attraverso l'uso del tasto [Tab]. Si preparano alcuni file di esempio. I nomi utilizzati sono volutamente lunghi.

touch microinterruttore[Invio]

touch microscopico[Invio]

touch supersonico[Invio]

Supponendo di voler utilizzare questi nomi all'interno di una riga di comando, si può essere un po' infastiditi dalla loro lunghezza. Utilizzando il completamento automatico si risolve il problema.

ls sup[Tab]

Dopo avere scritto solo `sup', premendo il tasto [Tab] si ottiene il completamento del nome, dal momento che non esistono altri file o directory (nella posizione corrente) che inizino nello stesso modo. L'esempio seguente mostra lo stesso comando completato e terminato.

ls sup[Tab]ersonico[Invio]

Il completamento automatico dei nomi potrebbe essere impossibile. Infatti, potrebbe non esistere alcun nome che coincida con la parte iniziale già inserita, oppure potrebbero esistere più nomi composti con lo stesso prefisso. In quest'ultimo caso, il completamento si ferma al punto in cui i nomi iniziano a distinguersi.

ls mic[Tab]ro

In questo caso, il completamento si spinge fino a `micro' che è la parte comune dei nomi `microinterruttore' e `microscopico'. Per poter proseguire occorre aggiungere un'indicazione che permetta di distinguere tra i due nomi. Volendo selezionare il primo di questi nomi, basta aggiungere la lettera `i' e premere nuovamente il tasto [Tab]. L'esempio seguente rappresenta il procedimento completo.

ls mic[Tab]roi[Tab]nterruttore[Invio]

5.9.2 Sostituzione: caratteri jolly

L'utilizzo di caratteri jolly rappresenta una forma alternativa di completamento dei nomi. Infatti è compito della shell la trasformazione dei simboli utilizzati per questo scopo.

Per questo esercizio si utilizzano i file creati nella sezione precedente: `microinterruttore', `microscopico' e `supersonico'. In seguito se ne aggiungeranno altri quando l'esercizio lo richiede.

5.9.2.1 Asterisco

L'asterisco rappresenta una sequenza indefinita di zero o più caratteri di qualunque tipo, esclusa la barra obliqua di separazione tra le directory. Per cui, l'asterisco utilizzato da solo rappresenta tutti i nomi di file disponibili nella directory corrente.

ls[Invio]

Il comando `ls' appena mostrato serve a elencare tutti i nomi di file e directory contenuti nella directory corrente.

ls *[Invio]

Questo comando è un po' diverso, nel senso che la shell provvede a sostituire l'asterisco con tutto l'elenco di nomi di file e directory contenuti nella directory corrente. Sarebbe come se il comando fosse `ls microinterruttore microscopico'...

In tal senso, anche il comportamento di `ls' cambia: non si limita a elencare il contenuto della directory corrente, ma (eventualmente, se ce ne sono) anche quello di tutte le directory contenute in quella corrente.

L'asterisco può essere utilizzato anche assieme a parti fisse di testo.

ls micro*[Invio]

Questo comando è composto in modo che la shell sostituisca `micro*' con tutti i nomi che iniziano per `micro'.

microinterruttore microscopico

È stato precisato che l'asterisco può essere sostituito anche con la stringa nulla. Per verificarlo si crea un altro file.

touch nanomicro[Invio]

Con il comando seguente si vogliono elencare tutti i nomi che contengono la parola `micro'.

ls *micro*[Invio]

microinterruttore microscopico nanomicro

5.9.2.2 Interrogativo

Il punto interrogativo rappresenta esattamente un carattere qualsiasi.

Prima di proseguire si aggiungono alcuni file con nomi adatti agli esempi seguenti.

touch xy123j4[Invio]

touch xy456j5[Invio]

touch xy789j111[Invio]

touch xy78j67[Invio]

Con il comando seguente si vuole intervenire su tutti i file lunghi esattamente sette caratteri e che contengono la lettera `j' nella sesta posizione.

ls ?????j?[Invio]

xy123j4 xy456j5

Diverso sarebbe stato usando l'asterisco: non si può limitare il risultato ai file che contengono la lettera `j' nella sesta posizione, e nemmeno la lunghezza del nome può essere presa in considerazione.

ls *j*[Invio]

In questo modo si ottiene l'elenco di tutti i nomi che contengono la lettera `j', senza specificare altro.

xy123j4 xy456j5 xy789j111 xy78j67

5.9.2.3 Parentesi quadre

Le parentesi quadre vengono utilizzate per delimitare un elenco o un intervallo di caratteri. Rappresentano un solo carattere tra quelli contenuti, o tra quelli appartenenti all'intervallo indicato.

ls xy????[4567]*[Invio]

xy123j4 xy456j5

Il comando appena indicato era stato scritto in modo da fornire a `ls', come argomento, l'elenco di tutti i file i cui nomi iniziano per `xy', proseguono con quattro caratteri qualunque, quindi contengono un carattere da `4' a `7' e terminano in qualunque modo. Lo stesso risultato si poteva ottenere indicando un intervallo nelle parentesi quadre.

ls xy????[4-7]*[Invio]

5.9.2.4 Escape

Il fatto che la shell sostituisca alcuni caratteri impedisce di fatto il loro utilizzo nei nomi di file e directory. Se esiste la necessità, è possibile evitare la sostituzione di questi facendoli precedere da una barra obliqua inversa, che funge da carattere di escape (ovvero, da simbolo di protezione).

touch sei\*otto[Invio]

ls[Invio]

...
sei*otto

In questo modo è possibile includere nel nome di un file anche lo spazio.

touch sei\ bella[Invio]

ls[Invio]

...
sei bella
sei*otto

È bene ricordare che esistono altri modi per evitare che la shell intervenga nell'interpretazione dei simboli usati nella riga di comando, ma questi vengono approfonditi nei capitoli dedicati alla shell.

5.9.2.5 Verifica

L'uso di caratteri jolly può essere pericoloso quando non si ha un'esperienza sufficiente a determinare l'effetto esatto del comando che ci si accinge a utilizzare. Ciò soprattutto quando si utilizzano per cancellare. Il modo migliore per verificare l'effetto della sostituzione dei caratteri jolly è l'uso del comando `echo', che si occupa semplicemente di visualizzare l'elenco dei suoi argomenti.

Per esempio, per sapere quali file e directory vengono coinvolti dal modello `micro*', basta il comando seguente:

echo micro*[Invio]

microinterruttore microscopico

Anche l'uso di `ls', come comando non distruttivo, può essere di aiuto per determinare l'estensione di un modello fatto di caratteri jolly. Ma `ls' mostra anche il contenuto delle directory che vengono indicate tra gli argomenti, quindi potrebbe distrarre un po' l'utilizzatore.

5.9.3 Ridirezione e pipeline

La shell consente di ridirigere l'output di un comando che normalmente sarebbe destinato allo schermo, oppure di inviare dati all'input di un comando, che altrimenti lo attenderebbe dalla tastiera.

5.9.4 Ridirezione

La ridirezione dirotta i dati in modo di destinarli a un file o di prelevarli da un file.

ls -l > elenco[Invio]

Questo comando genera il file `elenco' con il risultato dell'esecuzione di `ls'. Si può controllare il contenuto di questo file con `cat'.

cat elenco[Invio]

Anche l'input può essere ridiretto, quando il comando al quale si vuole inviare è in grado di riceverlo. `cat' è in grado di emettere ciò che riceve dallo standard input.

cat < elenco[Invio]

Si ottiene in questo modo la visualizzazione del contenuto del file `elenco', esattamente nello stesso modo di prima, quando questo nome veniva indicato semplicemente come argomento di `cat'. Ma adesso lo si invia attraverso lo standard input per mezzo dell'attività della shell.

La ridirezione dell'output, come è stata vista finora, genera un nuovo file ogni volta, eventualmente sovrascrivendo ciò che esiste già con lo stesso nome. Sotto questo aspetto, la ridirezione dell'output è fonte di possibili danni.

La ridirezione dell'output può essere fatta in aggiunta, creando un file se non esiste, o aggiungendovi i dati se è già esistente.

ls -l /tmp >> elenco[Invio]

In tal modo viene aggiunto al file `elenco' l'elenco dettagliato del contenuto della directory `/tmp/'.

cat elenco[Invio]

5.9.5 Pipeline

La pipeline è una forma di ridirezione in cui la shell invia l'output di un comando come input del successivo.

cat elenco | sort[Invio]

In questo modo, `cat' legge il contenuto del file `elenco', ma invece di essere visualizzato sullo schermo, viene inviato dalla shell come standard input di `sort' che lo riordina e poi lo emette sullo schermo.

Una pipeline può utilizzare anche la ridirezione, per cui, il comando visto precedentemente può essere trasformato nel modo seguente,

cat < elenco | sort[Invio]

o semplificato ancora come indicato sotto, ma in tal caso non si tratta più di pipeline.

sort < elenco[Invio]

5.9.6 Alias

La creazione di un alias è un metodo che permette di definire un nome alternativo per un comando preesistente.

alias elenca='ls -l'[Invio]

Dopo aver definito l'alias `elenca', come indicato nel comando precedente, utilizzandolo si ottiene l'equivalente di `ls -l'. Basta provare.

elenca[Invio]

Ma l'alias permette di utilizzare argomenti, come se si trattasse di comandi normali.

elenca micro*[Invio]

Quello che si ottiene corrisponde al risultato del comando `ls -l micro*'.

-rw-rw-r--   1 tizio    tizio           0 Dec 26 10:19 microinterruttore
-rw-rw-r--   1 tizio    tizio           0 Dec 26 10:19 microscopico

Gli alias tipici che vengono creati sono i seguenti. Servono per fare in modo che le operazioni di cancellazione o sovrascrittura vengano eseguite dopo una richiesta di conferma.

alias rm='rm -i'[Invio]

alias cp='cp -i'[Invio]

alias mv='mv -i'[Invio]

Si può provare a eliminare un file per vedere cosa accade.

rm microinterruttore[Invio]

rm: remove `microinterruttore'?:

n[Invio]

In questo modo, il file non è stato cancellato.

5.9.7 Conclusione

Il completamento dei nomi e i caratteri jolly sono gli strumenti operativi più importanti che una shell fornisce. Tuttavia, l'uso di modelli con caratteri jolly può essere fonte di errori anche gravi, e prima di utilizzarli in comandi distruttivi, conviene verificare l'effetto di questi modelli con `echo'.

La ridirezione e le pipeline sono un altro strumento importante che permette di costruire comandi molto complessi a partire da comandi elementari.

5.10 Controllo dei processi

In presenza di un ambiente in multiprogrammazione è importante il controllo dei processi in esecuzione. Un processo è un singolo eseguibile in funzione, ma un comando può generare diversi processi.

5.10.1 Visualizzazione dello stato dei processi

Il comando fondamentale per il controllo dei processi è `ps'.

ps[Invio]

  PID TTY STAT  TIME COMMAND
  077   1 SW   0:01 (login)
  078   2 SW   0:01 (login)
  091   1 S    0:01 -bash
  132   2 S    0:01 -bash
  270   1 R    0:00 ps 

In questo caso `ps' mostra che sono in funzione due copie di `bash' (la shell Bash), ognuna su un terminale differente (la prima e la seconda console virtuale), `tty1' e `tty2'. L'unico programma in esecuzione è lo stesso `ps', che in questo esempio è stato avviato dal primo terminale

Attraverso l'opzione `f', si può osservare la dipendenza tra i processi.

ps f[Invio]

  PID TTY STAT  TIME COMMAND
  077   1 SW   0:01 (login)
  091   1 S    0:01  \_ -bash
  275   1 R    0:00      \_ ps -f
  078   2 SW   0:01 (login)
  132   2 S    0:01  \_ -bash

Un modo graficamente più aggraziato di osservare la dipendenza tra i processi è dato da `pstree'.

pstree[Invio]

init-+-crond
     |-kflushd
     |-klogd
     |-kswapd
     |-login---bash
     |-login---bash---pstree
     |-4*[mingetty]
     |-4*[nfsiod]
     |-portmap
     |-rpc.mountd
     |-rpc.nfsd
     |-syslogd
     `-update

Mentre prima si vedevano solo i processi connessi ai terminali, adesso vengono visualizzati tutti i processi in funzione in modo predefinito. L'elenco cambia a seconda della configurazione del proprio sistema.

5.10.2 Eliminazione dei processi

I processi vengono eliminati automaticamente una volta che questi terminano regolarmente. A volte ci può essere la necessità di eliminare forzatamente un processo.

Per verificare questa situazione si può passare sulla seconda console virtuale e da lì avviare un programma inutile che verrà eliminato attraverso la prima console.

[Alt+F2]

Se fosse necessario eseguire l'accesso, è questo il momento di farlo.

yes[Invio]

y
y
y
y
...

Attraverso `yes' si ottiene un'emissione continua di lettere «y». Si può passare alla prima console e osservare la situazione.

[Alt+F1]

ps[Invio]

  PID TTY STAT  TIME COMMAND
  077   1 SW   0:01 (login)
  078   2 SW   0:01 (login)
  091   1 S    0:01 -bash
  132   2 S    0:01 -bash
  311   2 R    0:26 yes 

Si decide di eliminare il processo generato da `yes', e questo attraverso l'invio di un segnale di conclusione.

kill 311[Invio]

Il numero 311 è il numero abbinato al processo, o PID, che si ottiene osservando le informazioni emesse da `ps'. Tornando sulla console in cui era stato eseguito `yes' si potrà osservare che questo ha terminato di funzionare.

[Alt+F2]

...
y
y
Terminated

5.10.3 Processi sullo sfondo

Per mezzo della shell è possibile avviare dei comandi sullo sfondo, ovvero in background, in modo che si renda nuovamente disponibile l'invito per inserire altri comandi.

yes > /dev/null &[Invio]

Questo comando avvia `yes' dirottando l'output nel file `/dev/null' che in realtà è un dispositivo speciale paragonabile a una pattumiera senza fondo (tutto ciò che vi viene scritto è eliminato). Il simbolo e-commerciale (`&'), posto alla fine del comando, dice alla shell di eseguirlo sullo sfondo.

Naturalmente, ha senso eseguire un comando sullo sfondo quando questo non richiede input da tastiera e non emette output sul terminale.

5.10.4 Conclusione

Il controllo dei processi avviene essenzialmente attraverso `ps' e `kill'. La shell fornisce generalmente una forma di controllo sui comandi avviati attraverso di essa, e questi vengono definiti normalmente job di shell.

Il capitolo 26 e i successivi trattano meglio di questo argomento.

5.11 Permessi

I permessi definiscono i privilegi dell'utente proprietario, del gruppo e degli altri utenti nei confronti dei file e delle directory.

La sezione 4.7.5 introduceva i problemi legati ai permessi, in particolare spiegava il modo in cui si rappresentano in forma numerica.

5.11.1 Permessi sui file

Sui file possono essere regolati tre tipi di permessi: lettura scrittura ed esecuzione. Mentre il significato del permesso in esecuzione è abbastanza logico (riguarda i file eseguibili e gli script), e così anche quello in lettura, quello in scrittura potrebbe fare pensare che permetta di evitarne la cancellazione. Non è così, la possibilità di cancellare un file dipende dai permessi della directory.

touch mio_file[Invio]

chmod -r mio_file[Invio]

In questo modo è stato tolto il permesso in lettura a tutti gli utenti, anche al proprietario.

ls -l mio_file[Invio]

--w--w----   1 tizio    tizio           0 Dec 26 10:24 mio_file

Si può vedere che dalla stringa dei permessi è sparita la lettera `r'.

cat mio_file[Invio]

cat: mio_file: Permission denied

L'emissione sullo schermo del file è impossibile perché questo non ha il permesso in lettura (in questo caso il file è vuoto e non c'è proprio nulla da visualizzare, ma qui conta il fatto che il sistema si opponga alla lettura).

chmod +r mio_file[Invio]

Prima di verificare cosa accade togliendo il permesso in scrittura conviene ripristinare il permesso in lettura, con il comando appena visto.

chmod -w mio_file[Invio]

In questo modo viene tolto il permesso in scrittura, cosa che impedisce la modifica del file, ma non la sua cancellazione.

ls > mio_file[Invio]

bash: mio_file: Permission denied

Un tentativo di sovrascrittura genera una segnalazione di errore, come nell'esempio appena visto, così come qualunque altro tentativo di modificare il suo contenuto.

mv mio_file tuo_file[Invio]

Lo spostamento o il cambiamento del nome è possibile.

ls -l tuo_file[Invio]

-r--r--r--   1 tizio    tizio           0 Dec 26 10:24 tuo_file

Anche la cancellazione è ammissibile; probabilmente si ottiene un avvertimento, ma niente di più.

rm tuo_file[Invio]

rm: remove `tuo_file', overriding mode 0444? 

y[Invio]

Il file, alla fine, viene cancellato.

5.11.2 Permessi sulle directory

Sulle directory possono essere regolati tre tipi di permessi: lettura scrittura ed esecuzione. Per chi non conosce già un sistema operativo Unix, il significato potrebbe non essere tanto intuitivo.

mkdir provedir[Invio]

touch provedir/uno[Invio]

touch provedir/due[Invio]

Togliendo il permesso in lettura si impedisce la lettura del contenuto della directory, cioè si impedisce l'esecuzione di un comando come `ls', mentre l'accesso ai file continua a essere possibile (purché se ne conoscano i nomi).

chmod -r provedir[Invio]

ls provedir[Invio]

ls: provedir: Permission denied

Prima di proseguire si ripristinano i permessi in lettura.

chmod +r provedir[Invio]

I permessi in scrittura consentono di aggiungere, eliminare e rinominare i file (e le eventuali sottodirectory).

chmod -w provedir[Invio]

Questo comando toglie il permesso di scrittura della directory `provedir/'.

rm provedir/uno[Invio]

rm: provedir/uno: Permission denied

cp provedir/uno provedir/tre[Invio]

cp: cannot create regular file `provedir/tre': Permission denied

mv provedir/uno provedir/tre[Invio]

mv: cannot move `provedir/uno' to `provedir/tre': Permission denied

Prima di proseguire si ripristina il permesso in scrittura.

chmod +w provedir[Invio]

Il permesso di esecuzione è il più strano. Impedisce l'accesso alla directory e a tutto il suo contenuto. Ciò significa che non è possibile accedere a file o directory discendenti di questa.

Viene creata una directory discendente da `provedir/'.

mkdir provedir/tmp[Invio]

Si crea un file al suo interno, per poter verificare in seguito quanto detto.

touch provedir/tmp/esempio[Invio]

Si tolgono i permessi in esecuzione a `provedir/' per vedere cosa accade.

chmod -x provedir[Invio]

Da questo momento, `provedir/' e tutto quello che ne discende è inaccessibile.

cd provedir[Invio]

bash: cd: provedir: Permission denied

cat provedir/tmp/esempio[Invio]

cat: provedir/tmp/esempio: Permission denied

touch provedir/tmp/esempio2[Invio]

touch: provedir/tmp/esempio2: Permission denied

5.11.3 Maschera dei permessi: umask

La maschera dei permessi, ovvero la maschera umask, determina i permessi che devono essere tolti quando si crea un file o una directory e non si definiscono esplicitamente i loro permessi. Nello stesso modo, quando si attribuiscono dei permessi senza definire a quale livello si riferiscono (all'utente, al gruppo o agli altri, come è stato fatto nelle sezioni precedenti), vengono tolti quelli della maschera dei permessi. Per conoscere il valore di questa maschera basta il comando seguente:

umask[Invio]

002

Se il sistema è configurato come era stato suggerito all'inizio di questo capitolo, è questo il valore che viene restituito. Frequentemente, il valore della maschera dei permessi è 022.

Il numero due rappresenta un permesso in scrittura, in questo caso riferito agli utenti differenti dal proprietario e dal gruppo di appartenenza. Questo significa che il permesso viene tolto in modo predefinito. Se il valore fosse stato 022, anche al gruppo verrebbe tolto il permesso di scrittura.

Si può ottenere una rappresentazione della maschera dei permessi più espressiva, con l'opzione `-S'.

umask -S[Invio]

u=rwx,g=rwx,o=rx

In tal caso si è ottenuta la rappresentazione dei permessi che vengono concessi in modo predefinito.

Si suppone, per esercizio, di trovarsi nella situazione di volere difendere i propri dati da qualunque accesso da parte degli altri utenti (a parte l'utente `root' al quale nulla può essere impedito).

umask 077[Invio]

Il numero sette rappresenta tutti i permessi (lettura, scrittura ed esecuzione), e questi verranno tolti sistematicamente al gruppo e agli altri utenti. Per verificarlo si può provare a creare un file.

touch segreto[Invio]

ls -l segreto[Invio]

-rw-------   1 tizio    tizio           0 Dec 27 11:10 segreto

`touch' non ha tentato di attribuire dei permessi in esecuzione, quindi questo non appare tra quelli dell'utente proprietario.

mkdir segreta[Invio]

ls -l[Invio]

...
drwx------   2 tizio    tizio        1024 Dec 27 11:14 segreta
...

Come si vede dall'esempio, anche la creazione di directory risente della maschera dei permessi.

5.11.4 Conclusione

Il significato dei permessi di file e directory non è necessariamente intuitivo o evidente. Un po' di allenamento è necessario per comprenderne il senso.

La maschera dei permessi, o umask, è un mezzo con cui filtrare i permessi indesiderati nelle operazioni normali, quelle in cui questi non vengono espressi in modo preciso.

5.12 Creazione e modifica di file di testo

In tutti i corsi di Unix si mostra l'uso di un applicativo storico, e per questo anche piuttosto spartano, per la creazione e la modifica di file di testo: VI. Questo poi si concretizza in pratica nell'eseguibile `vi'. La necessità di imparare a usare questo programma, almeno in modo elementare, sta nel fatto che utilizza poche risorse di memoria e spesso fa parte dell'insieme di programmi di utilità che compongono i dischetti di emergenza.

5.12.1 Modalità di comando e di inserimento

L'uso di VI è difficile perché si distinguono diverse modalità di funzionamento. In pratica si separa la fase di inserimento del testo da quella in cui si inseriscono i comandi.

Per poter inserire un comando occorre sospendere l'inserimento con la pressione di [Esc]. Per poter ritornare alla modalità di inserimento occorre dare un comando apposito.

Il tasto [Esc] può essere usato anche per annullare un comando che non sia stato completato. Se premuto più del necessario non produce alcun effetto collaterale.

5.12.2 Creazione, inserimento e modifica

Si crea un nuovo file semplicemente avviando il programma senza argomenti.

vi[Invio]

Appena avviato, VI impegna tutto lo schermo.

_
~
~
~
~
~
Empty buffer

I simboli tilde (`~') rappresentano righe nulle (inesistenti).

In questo momento il programma si trova in modalità di comando e accetta comandi espressi attraverso lettere o simboli della tastiera.

5.12.2.1 Inserimento di testo

Con il tasto [i], che rappresenta il comando di inserimento (insert), si passa alla modalità di inserimento attraverso la quale si può digitare del testo normalmente.

[i]

Linux è un sistema operativo completo[Invio]

il cui kernel è stato scritto da[Invio]

Linus Torvalds e altri collaboratori.

Quello che si vede sullo schermo dovrebbe apparire come l'esempio che segue, con il cursore alla fine dell'ultima frase digitata.

Linux è un sistema operativo completo
il cui kernel è stato scritto da
Linus Torvalds e altri collaboratori._
~
~
~
-- INSERT --

Si termina la modalità di inserimento e si torna a quella di comando attraverso la pressione del tasto [Esc].

[Esc]

5.12.2.2 Spostamento del cursore

Lo spostamento del cursore attraverso il testo avviene in modalità di comando, con i tasti [h], [j], [k] e [l] che corrispondono rispettivamente allo spostamento a sinistra, in basso, in alto e a destra. Nella maggior parte delle situazioni possono essere utilizzati i tasti freccia, anche durante la fase di inserimento.

Si decide di spostare il cursore davanti alla parola «completo» della prima riga.

[h][h][h][h][h][h][h][h][h]

[k][k]

In pratica si sposta il cursore a sinistra di 9 posizione e in alto di due.

Linux è un sistema operativo_completo
il cui kernel è stato scritto da
Linus Torvalds e altri collaboratori.
~
~
~

5.12.2.3 Cancellazione

La cancellazione di testo in modalità di comando avviene attraverso l'uso del tasto [x]. Si ottiene la cancellazione del carattere che si trova in corrispondenza del cursore, avvicinando il testo rimanente dalla destra.

Nella maggior parte dei casi può essere usato anche il tasto [Canc] con questo scopo, e quest'ultimo, in particolare, dovrebbe funzionare sia in modalità di comando che di inserimento.

Si decide di cancellare la parola «completo».

[x][x][x][x][x][x][x][x][x]

Linux è un sistema operativo_

La cancellazione di una riga intera si ottiene con il comando `dd' ovvero con la pressione del tasto [d] per due volte di seguito.

Si decide di cancellare l'ultima riga. Per prima cosa si sposta il cursore sopra con il tasto [j], premuto per due volte, quindi si procede con la cancellazione.

[j][j]

[d][d]

Linux è un sistema operativo
il cui kernel è stato scritto da
~
~
~
~

5.12.3 Salvataggio e conclusione

Il salvataggio del testo in un file si ottiene attraverso un comando più complesso di quelli visti finora. Dalla modalità di comando si preme il tasto [:] che inizia un comando speciale, detto colon o ultima riga, perché appare sull'ultima riga dello schermo.

[:]

Linux è un sistema operativo
il cui kernel è stato scritto da
~
~
~
~
:_

Il comando per salvare è

:w <nome-file>

e si decide di salvare con il nome `miotesto'.

w miotesto

Sullo schermo dovrebbe apparire come si vede di seguito.

Linux è un sistema operativo
il cui kernel è stato scritto da
~
~
~
~
:w miotesto_

Si conclude con la pressione del tasto [Invio].

[Invio]

La conclusione del funzionamento di VI si ottiene con il comando `:q'. Se si pretende di terminare senza salvare occorre imporre il comando con l'aggiunta di un punto esclamativo (`:q!').

:q[Invio]

5.12.4 Apertura di un file esistente

Per avviare l'eseguibile `vi' in modo che questo apra immediatamente un file già esistente per permetterne la modifica, basta indicare il nome di questo file nella riga di comando.

vi miotesto[Invio]

Linux è un sistema operativo
il cui kernel è stato scritto da
~
~
~
~
``miotesto'' 1 line, 62 characters

In alternativa si può utilizzare il comando `:e' con la sintassi seguente:

:e <nome-file>

Il risultato è lo stesso.

5.12.5 Conclusione

VI è un applicativo per la creazione e la modifica di file di testo, molto poco elaborato esteticamente e piuttosto complicato da utilizzare. Tuttavia è necessario saperlo usare nelle occasioni in cui non è disponibile un programma migliore, o non è possibile usare altro a causa delle ristrettezze del sistema.

Questo esercizio sull'uso di VI è solo un minimo assaggio del funzionamento di questo programma, che, al contrario di quanto possa sembrare, offre molti accorgimenti e potenzialità che alla lunga possono rivelarsi veramente utili. Il capitolo 67 mostra un po' meglio le possibilità di questo e di altri programmi del genere.

5.13 Ricerche

Le ricerche di file e directory sono molto importanti in presenza di un filesystem articolato come quello di GNU/Linux, o di Unix in generale.

5.13.1 Find

Le ricerche di file e directory in base al nome e altre caratteristiche esterne, vengono effettuate attraverso il comando `find'.

find / -name bash -print[Invio]

Questo comando esegue una ricerca per i file e le directory denominati `bash' all'interno di tutte le directory che si articolano a partire dalla radice.

/bin/bash
...
find: /var/run/sudo: Permission denied
find: /var/spool/at: Permission denied
find: /var/spool/cron: Permission denied
...

Il file viene trovato, ma tutte le volte che `find' tenta di attraversare directory per cui non si ha il permesso, si ottiene una segnalazione di errore.

Le ricerche basate sul nome possono impiegare anche caratteri jolly, ma in tal caso deve essere `find' a gestirli, e non la shell, di conseguenza si deve fare in modo che quest'ultima non intervenga.

find / -name \*sh -print[Invio]

L'uso della barra obliqua inversa prima dell'asterisco permette di evitare che la shell tenti di interpretarlo come carattere jolly. Alla fine, `find' riceve l'argomento corretto, senza barra davanti all'asterisco.

/bin/bash
/bin/ash
/bin/sh
...

5.13.2 Grep

Per le ricerche all'interno dei file si utilizza `grep'.

grep tizio /etc/*[Invio]

/etc/group:tizio::500:tizio
/etc/passwd:tizio:Ide2ncPYY1234:500:500:Tizio Tizi:/home/tizio:/bin/bash
grep: /etc/skel: Is a directory
grep: /etc/sudoers: Permission denied
...

Il risultato che si ottiene dal comando di esempio, sono i nomi dei file contenenti la parola «tizio» e la riga in cui questo appare. Anche in questo caso si possono incontrare file per i quali non si hanno i permessi, o directory, per le quali l'uso di `grep' non ha alcun significato.

5.13.3 Conclusione

I comandi `find' e `grep' sono la base su cui si fondano le ricerche di file con il sistema GNU/Linux. Questi due possono essere anche combinati insieme in modo da definire una ricerca in base a caratteristiche esterne e interne ai file. L'argomento viene trattato nel capitolo 61.

5.14 Dischi e filesystem

La gestione dei dischi nei sistemi Unix appare piuttosto laboriosa per chi si avvicina la prima volta alla sua filosofia. La sezione 4.4.3 introduceva l'argomento.

I dischetti che si utilizzeranno in questo esercizio non devono essere protetti contro la scrittura.

5.14.1 Inizializzazione

L'inizializzazione o formattazione di un disco ha due fasi: la predisposizione delle tracce e dei settori e la preparazione di un filesystem. La prima fase è detta anche formattazione a basso livello e normalmente viene eseguita solo sui dischetti.

Prima di procedere occorre ottenere i privilegi dell'utente `root'.

su[Invio]

Password: ameba[Invio]

Prima di iniziare con la formattazione a basso livello si deve verificare il nome del dispositivo utilizzato nel proprio sistema, infatti ci possono essere differenze sotto questo aspetto da un'installazione all'altra. Si presume di potere utilizzare dischetti da 3,5 pollici con un formato di 1440 Kbyte.

ls /dev/fd0?1440[Invio]

Si potrebbero ottenere i nomi `/dev/fd0u1440' e `/dev/fd0h1440', oppure `/dev/fd0H1440' e il solito `/dev/fd0h1440'. Quello che serve è `/dev/fd0u1440' oppure `/dev/fd0H1440'.

Si procede con la formattazione a basso livello del dischetto (qui si mostra il caso in cui si debba utilizzare il dispositivo `/dev/fd0u1440').

fdformat /dev/fd0u1440[Invio]

Double-sided, 80 tracks, 18 sec/track. Total capacity 1440 kB.
Formatting ... done
Verifying ... done

Se non esiste il programma eseguibile `fdformat', dovrebbe essere presente al suo posto `superformat', che può essere usato nello stesso modo, anche se i messaggi che genera sono differenti.

Se questo è l'esito che si ottiene, il dischetto è stato formattato con successo. Prima di procedere oltre è necessario formattare altri due dischetti.

I dischetti formattati a basso livello non sono ancora adatti a contenere dati in forma di directory e file. Occorre creare un filesystem.

mkfs.msdos /dev/fd0[Invio]

mkfs.msdos 0.3b (Yggdrasil), 5th May 1995 for MS-DOS FS

In questo modo è stato creato un filesystem di tipo Dos-FAT nel dischetto formattato precedentemente a basso livello. Il messaggio che si ottiene può variare da un'installazione di GNU/Linux a un'altra, ma questo non è molto importante.

Dopo avere sostituito il dischetto si esegue il comando seguente allo scopo di creare un filesystem Minix.

mkfs.minix /dev/fd0[Invio]

480 inodes
1440 blocks
Firstdatazone=19 (19)
Zonesize=1024
Maxsize=268966912

Dopo avere sostituito il dischetto si esegue il comando seguente allo scopo di creare un filesystem Second-extended (definizione abbreviata generalmente con la sigla Ext2).

mkfs.ext2 /dev/fd0[Invio]

mke2fs 1.10, 24-Apr-97 for EXT2 FS 0.5b, 95/08/09
Linux ext2 filesystem format
Filesystem label=
360 inodes, 1440 blocks
72 blocks (5.00%) reserved for the super user
First data block=1
Block size=1024 (log=0)
Fragment size=1024 (log=0)
1 block group
8192 blocks per group, 8192 fragments per group
360 inodes per group

Writing inode tables: done     
Writing superblocks and filesystem accounting information: done

Per proseguire l'esercizio si devono distinguere i tre dischetti appena preparati, in modo da sapere riconoscere quale utilizza il filesystem Dos, quale quello Minix e quale quello Ext2.

5.14.2 Montare e smontare i dischetti

Nei sistemi Unix e derivati, per poter accedere a un'unità di memorizzazione occorre che il filesystem di questa sia montato in quello globale. Non si può indicare semplicemente una directory o un file di un certo dispositivo. Il montaggio è l'operazione con cui si innesta il filesystem di un'unità di memorizzazione in corrispondenza di una directory del filesystem già attivo. La directory che si utilizza generalmente per montare provvisoriamente le unità esterne è `/mnt/'.

Si procede inserendo il dischetto formattato con il formato Ext2 (quello nativo per il kernel Linux) e montandolo nella directory `/mnt/'.

mount -t ext2 /dev/fd0 /mnt[Invio]

Da questo momento, la directory `/mnt/' è l'inizio del dischetto.

touch /mnt/super.ultra.mega.macro[Invio]

Con il comando appena visto, si vuole creare un file vuoto con un nome piuttosto lungo. Volendo si possono copiare dei file nel dischetto.

cp /bin/bash /mnt[Invio]

Solitamente, l'invito della shell torna a disposizione prima che le operazioni di scrittura siano state completate, e questo a causa della presenza di una «memoria di transito», o più precisamente di una memoria cache. Anche per questo motivo, il dischetto non può essere estratto semplicemente alla fine delle operazioni che con questo si vogliono svolgere.

Finché il dischetto risulta montato, si può trattare come parte del filesystem globale.

ls -l /mnt[Invio]

total 418
-rwxr-xr-x   1 root     root       412516 Dec 28 13:10 bash*
drwxr-xr-x   2 root     root        12288 Dec 28 12:37 lost+found/
-rw-r--r--   1 root     root            0 Dec 28 13:05 super.ultra.mega.macro

Si può osservare che il dischetto contiene il file creato all'inizio, l'eseguibile `bash' copiato in precedenza, e una directory particolare: `lost+found/'. Questa viene creata automaticamente assieme al filesystem Ext2. Generalmente può essere cancellata se la sua presenza infastidisce. In un certo senso, la presenza di questa directory è utile per scorgere l'inizio di un filesystem montato in quel punto particolare.

Si procede sostituendo il dischetto con quello contenente un filesystem Minix. Per fare questo occorre prima smontare il dischetto inserito attualmente, e quindi montare il secondo.

umount /mnt[Invio]

A questo punto, al ritorno dell'invito della shell, si possono sostituire i dischetti.

mount -t minix /dev/fd0 /mnt[Invio]

Per esercizio, si fanno le stesse operazioni di prima.

touch /mnt/super.ultra.mega.macro[Invio]

cp /bin/bash /mnt[Invio]

ls -l /mnt[Invio]

total 404
-rwxr-xr-x   1 root     root       412516 Dec 28 13:31 bash*
-rw-r--r--   1 root     root            0 Dec 28 13:31 super.ultra.mega.macro

Come si può osservare, il filesystem Minix non prevede la presenza della directory `lost+found/'. Un'altra cosa da notare è che il file con quel nome lungo è stato memorizzato nel modo corretto, ma in ogni caso, in un filesystem Minix i nomi non possono superare i 30 caratteri.

umount /mnt[Invio]

A questo punto si ripetono le stesse cose con il dischetto Dos-FAT.

mount -t msdos /dev/fd0 /mnt[Invio]

touch /mnt/super.ultra.mega.macro[Invio]

cp /bin/bash /mnt[Invio]

ls -l /mnt[Invio]

total 403
-rwxr-xr-x   1 root     root       412516 Dec 28 14:02 bash*
-rwxr-xr-x   1 root     root            0 Dec 28 14:01 super.ult*

Trattandosi di un dischetto con un filesystem Dos-FAT, le cose non sono andate come in precedenza. Prima di tutto, i permessi dei file non corrispondono agli esempi già visti: in pratica, tutti i file hanno gli stessi permessi. L'utente proprietario di tutti i file è `root' essendo stato lui a montare il dischetto. I nomi dei file vengono troncati.

Volendo utilizzare un dischetto Dos-FAT per memorizzare nomi lunghi, nello stesso modo in cui fa MS-Windows 95/98, si poteva montare facendo riferimento al tipo di filesystem `vfat', mentre la formattazione del dischetto avviene sempre nello stesso modo.

Prima di concludere l'esercizio, si smonta il dischetto.

umount -t msdos /dev/fd0 /mnt[Invio]

È il caso di ricordare che non è possibile smontare un disco se prima non è terminata l'attività con questo. Per cui, se la directory corrente è posizionata su una directory appartenente al filesystem del disco che si vuole smontare, non si riesce a eseguire l'operazione di distacco.

5.14.3 Conclusione

La gestione delle unità di memorizzazione può sembrare complicata fino a che non se ne comprende la logica. La cosa più importante da capire è che non si può accedere al contenuto di un disco se prima questo non viene montato, e che non si può estrarre un disco se prima non è stato smontato.

A partire dal capitolo 51 vengono trattati questi argomenti.

È il caso di ricordare che l'esercizio è stato svolto operando come utente `root', per cui, prima di proseguire, è meglio ritornare allo stato normale.

exit[Invio]

5.15 Dispositivi

Nei sistemi Unix, i dispositivi sono manifestati da file speciali collocati nella directory `/dev/'. L'utilizzo diretto dei dispositivi è spesso un'operazione delicata, che può essere eseguita solo dall'utente `root'. Alcuni esercizi di questa sezione vanno svolti come utente `root', e in tal caso si noterà l'invito della shell, che negli esempi viene rappresentato dal simbolo `#'.

5.15.1 /dev/null

Il file di dispositivo `/dev/null' corrisponde in lettura a un file vuoto, e in scrittura a una sorta di buco senza fondo: tutto ciò che vi viene scritto è perduto. Questa particolarità è molto utile negli script in cui si vuole evitare che i comandi contenuti emettano segnalazioni all'utente.

ls /bin > /dev/null[Invio]

Il comando appena mostrato non emette nulla sullo schermo perché tutto viene ridiretto verso `/dev/null'. Si può verificare che in questo file non ci sia più alcuna traccia con il comando seguente:

cat /dev/null[Invio]

Non si ottiene alcun output.

5.15.2 Dispositivi di memorizzazione

La gestione diretta dei dispositivi di memorizzazione è un'operazione delicata e richiede i privilegi dell'utente `root'.

su[Invio]

Password: ameba[Invio]

I dispositivi di memorizzazione possono essere gestiti come se fossero dei file. In pratica, un dischetto da 1440 Kbyte può essere trattato come se si trattasse di un file della stessa dimensione.

Nell'esercizio sulle unità di memorizzazione sono stati formattati alcuni dischetti, e vi è stato copiato dentro qualcosa.

Si procede in modo da generare un file-immagine di un dischetto di quelli preparati in precedenza. Si inserisce uno di quei dischi.

cp /dev/fd0 disco.img[Invio]

Il dischetto di cui è stata fatta la copia in un file-immagine non è stato montato in precedenza, e tuttora non risulta montato.

ls -l disco.img[Invio]

-rw-r-----   1 root     root      1474560 Dec 28 14:59 disco.img

Volendo eseguire la copia del dischetto a cui appartiene questa immagine, basta sostituirlo con un altro che sia già stato formattato a basso livello (con `fdformat' per esempio, o con un altro sistema operativo con gli strumenti che questo mette a disposizione), e quindi copiare il file-immagine sul file di dispositivo corrispondente al dischetto.

Si sostituisce il dischetto e si procede.

cp disco.img /dev/fd0[Invio]

Il dischetto conterrà la copia identica di quello di partenza.

5.15.3 Conclusione

L'accesso diretto ai file di dispositivo è un metodo utilizzato particolarmente per la riproduzione di dischi (prevalentemente dischetti) in modo da conservare tutte le informazioni in essi contenuti. Questa tecnica viene usata specialmente per la trasmissione e la riproduzione di dischetti di sistemi operativi differenti, ed è normalmente ciò che si fa quando, a partire dal Dos, si devono preparare i primi dischetti di installazione di GNU/Linux.

5.16 Riferimenti

---------------------------

Appunti Linux 2000.04.12 --- Copyright © 1997-2000 Daniele Giacomini --  daniele @ pluto.linux.it


1.) Negli esempi che si vedono si presume di poter entrare nella directory personale di un altro utente. Tuttavia, questo dipende dai permessi che questo gli attribuisce.

2.) Per la precisione, sarebbe più opportuno l'uso del comando `echo', che però non è ancora stato mostrato.


[inizio] [indice generale] [precedente] [successivo] [indice analitico] [contributi]