• Non ci sono risultati.

DI FUSCO FRANCESCO

N/A
N/A
Protected

Academic year: 2021

Condividi "DI FUSCO FRANCESCO"

Copied!
123
0
0

Testo completo

(1)

VERSIONE 0.18

DI FUSCO FRANCESCO

INTRODUZIONE AL

SISTEMA

OPERATIVO LINUX

(2)

“Se ascolto dimentico, se vedo ricordo, se faccio capisco”

1

1 Confucio

(3)

Indice

Capitolo 1: Introduzione a Linux

Obiettivi

Che cos'è Linux ?

Installare Linux

Capitolo 2: I processi

I processi

Comandi per controllare il vostro sistema

kill

Terminare i processi

Processi di background

Capitolo 3: Avvio di Linux

Lavorare con Linux

Lavorare come altro utente

Distribuzioni

I runlevel

Avviare i processi nei runlevel

Il processo init

Controllare init

Arrestare init

Capitolo 4

Creare le vostre routine in Linux

Il file system di Linux

Ogni cosa è un file in Linux

Capitolo 5

Giorno per giorno con Linux

Terminali virtuali

Editor di testo in Linux

Capitolo 6

Shell in Linux

Comandi della shell frequentemente usati

Capitolo 7

Pipe

Capitolo 8

Ottenere più informazioni con Linux

Capitolo 9

Il comando grep

Altri comandi più interessanti

Capitolo 10

Potenti comandi utente

tee

>

2>

whoami

whereis

which

(4)

echo

wc

Capitolo 11

Comandi vari

Capitolo 12

Diventare superutente

Capitolo 13: Il filesystem in Linux

Il filesystem in Linux

Montare i file system

Opzioni di montaggio del filesystem

Il comando umount - smontare i file system

Partizionamento

Gerarchia delle directory

Le directory

I tipi di filesystem

Creare un filesystem

Buffering del filesystem

/etc/fstab

Capacità dei filesystem

Controllare e riparare i filesystem

Filesystem speciali

Operazioni sul filesystem

Creazione di una directory

Il comando mkdir

Rimozione di una directory

Il comando rmdir

Copia di file e directory

Il comando cp

Rimozione di file e directory

Il comando mv

Spostare file o directory

Elencare i file in una directory

I caratteri jolly

La struttura base delle directory in Linux

Capitolo 14

chmod

Permesso sui file in Linux

usare chown

Capitolo 15

Backup dei vostri file

Comprimere i file

Decomprimere i file

Capitolo 16

Installazione di programmi

Aggiornamenti

Capitolo 17

Stampare sotto Linux

Usare Linux per accedere ad Internet

(5)

Capitolo 18

Suono in Linux

Registrare il suono

Formato mp3

Formato ogg

Capitolo 19

Interfaccia grafica utente per Linux

L'albero della famiglia di GUI

Configurazione di X-Windows

Browser internet

client email

Capitolo 20

Amministrazione del sistema

Il ruolo di root

Delegare l'autorità

Aver cura quando si lavora come root

Come amministrare gli utenti del sistema

Amministrazione degli utenti

Altre occupazioni dell'amministratore

Modificare i file di configurazione

Capitolo 21

Automazione dei task

Automazione dei task in Linux

Capitolo 22

Strumenti dell'amministratore

Editor di testo

vi

emacs

editor di testo alternativi

Kate

kwrite

Elaborazione e manipolazione del testo

Capitolo 23

Il kernel di Linux

Che cos'è il kernel di Linux

Configurazione del kernel

Capitolo 24

I servizi del sistema

(6)
(7)

Capitolo 1

Introduzione a Linux

(8)

Che cos'è Unix

Il sistema operativo UNIX fu originariamente sviluppato presso i Bell Laboratories, un tempo parte del gigante delle telecomunicazioni AT&T. Progettato negli anni '70 per i computer PDP della Digital Equipment, è diventato un sistema operativo multiutente e multitasking molto popolare, disponibile per una gran varietà di piattaforme hardware, dalle workstation fino a server multiprocessori e supercomputer.

Nel 1965, i Bell Telephone Laboratories unirono i loro sforzi a quelli della General Electric Company nel progetto MAC del MIT (Massachussets Institute of Technology) per sviluppare un nuovo Sistema Operativo.

Il nome di quest'ultimo era Multics, acronimo di Multiplexed Information and Computing Service, dove

``multiplexed'' si riferisce alla combinazione di più segnali elettronici in un unico segnale. Si voleva far accedere simultaneamente un'ampia comunità di utenti al computer, fornire una grande potenza di calcolo e permettere agli utenti di condividere facilmente i loro dati, se necessario. Nel 1969, su un computer GE 645 girava una versione primitiva di Multics, che però non forniva il servizio computazionale che ci si era proposti inizialmente; inoltre non era chiaro quando sarebbe terminato il progetto, anche perché le tre entità coinvolte avevano obiettivi diversi. Quindi i Laboratori Bell abbandonarono il progetto, rimanendo però senza un Sistema Operativo adatto al lavoro da svolgere.

Per migliorare l'ambiente di programmazione disponibile, Ken Thompson, Dennis Ritchie e altri abbozzarono il progetto di un file system, la cui successiva evoluzione condusse a una prima versione del file system di UNIX. Thompson scrisse dei simulatori del comportamento del file system proposto e dei programmi in un ambiente demand-paging, oltre a un semplice kernel per il computer GE 645. Allo stesso tempo, scrisse un programma in FORTRAN di nome ``Space Travel'', per un sistema GECOS (Honeywell 635), ma il programma era insoddisfacente perché era difficile controllare la ``navicella spaziale'' e il costo dell'esecuzione era eccessivo. Successivamente Thompson trovò un computer DEC (Digital Equipment Corporation) PDP-7 scarsamente usato, che offriva un buon display grafico ed era economico in termini di potenza richiesta per l'esecuzione. Il porting di Space Travel sul PDP-7 permise a Thompson di familiarizzare con quel computer, il cui ambiente di sviluppo software però richiedeva l'utilizzo del cross- assembly sulla macchina GECOS e il trasporto del nastro magnetico, che serviva da input per il PDP-7. Per ottenere un ambiente di programmazione migliore, Thompson e Ritchie implementarono il loro progetto sul PDP-7, includendo una prima versione del file system di UNIX, il sottosistema dei processi e un piccolo insieme di utilità Il nuovo sistema così ottenuto era autoconsistente, non richiedendo il GECOS come ambiente di sviluppo, e fu chiamato Unics, come gioco di parole sul nome di Multics, coniato da un altro membro del Computing Science Research Center, Brian Kernighan.

(9)

Figura 1.1:

Dennis Ritchie e Ken Thompson (seduto) sviluppano un sistema operativo general purpose per computer che può gestire una varietà di applicazioni – dalla gestione di una rete di telecomunicazioni ad un word processor. UNIX è il primo software progettato per funzionare su computer di tutte le dimensioni da differenti produttori. E' il cuore di molti sistemi operativi che fanno funzionare la rete di telecomunicazioni della nazione, inclusa internet,

Tale nome evidenziava il fatto che il sistema in questione era più piccolo e meno ambizioso di Multics e, almeno inizialmente, era monoutente;

inoltre, ogni parte del sistema era progettata per svolgere al meglio un unico compito. Unics stava per ``UNiplexed Information and Computing System''; tale nome fu presto cambiato in Unix.

(10)

Che cos'è Linux

Linux è una implementazione liberamente distribuibile di un kernel simil-Unix, il nucleo a basso livello di un sistema operativo. Poiché Linux si ispira al sistema UNIX, i programmi per Linux e UNIX sono molto simili. Infatti, quasi tutti i programmi scritti per UNIX possono essere compilati ed eseguiti sotto Linux.

Inoltre, molte applicazioni commerciali vendute per UNIX possono essere eseguite senza modifiche in forma binaria sui sistemi Linux. Linux fu sviluppato da Linus Torvalds2 quando era studente alla Università di Helsinki, con l'aiuto dei programmatori UNIX tramite internet. Divenne poi un hobby inspirato dal sistema Minix di Andy Tanenbaum, un piccolo sistema UNIX, ma è cresciuto fino a diventare un completo sistema UNIX. Il kernel di Linux non usa il codice originale di UNIX di AT&T o qualsiasi altro codice proprietario.

2 Quando Linus Torvalds era studente all'Università di Helsinki, stava usando una versione del sistema operativo UNIX chiamato 'Minix'. Linus ed altri utenti fecero delle richieste di modifiche e miglioramenti al creatore di Minix, Andrew Tanenbaum, ma questi riteneva che non fossero necessarie. Fu così che Linus decise di creare il suo proprio sistema operativo che avrebbe preso in considerazione i commenti ed i suggerimenti di miglioramento degli utenti.

(11)

Crono storia della nascita di un pinguino

01/07/91

Tutto inizia in un'estate finlandese, Linus Benedict Torvalds, ancora un giovane studente dell' Università di Helsinki, inizia a lavorare al suo hobby: Linux.

Il 3 Luglio lo si sente informarsi su usenet:

"Hello netlanders, Due to a project I'm working on (in minix), I'm interested in the posix standard definition.

Could somebody please point me to a (preferably) machine-readable format of the latest posix rules? Ftp- sites would be nice. "

Torvalds giustificherà poi la folle impresa con queste parole: "I couldn't afford some of the commercial OSes and I didn't want to run DOS or Windows -- I don't even know, did Windows really exist then?".

5 Ottobre 1991 Nello stesso anno viene rilasciata la versione 0.02. Il post su usenet che ne annuncia la presenza è diventato un classico.

Grazie all'archivio di 20 anni di storia di Usenet su Google possiamo ricordare.

Gennaio 1992 Viene rilasciata la versione 0.12. Risulta relativamente stabile e supporta vario hardware.

Da questa versione in poi la crescita di Linux inizia a diventare progressiva e dirompente, sia come numero di coder che supportano lo sviluppo, sia come utilizzatori.

"Earlier kernel releases were very much only for hackers: 0.12 actually worked quite well"

Aprile 1992 Rilasciate la versione 0.95 e 0.96. Il salto è diretto dalla 0.12. Nascono le prime distribuzioni: la MCC Linux e la SLS.

1994 Viene rilasciata la prima versione definitiva 1.0.

Nascono RedHat, Debian, SUSE tutt'ora fra le distribuzioni più diffuse.

Linux, che resta protetto da copyright da Linux Torvalds, diventa ufficialmente un software aperto, abbracciando in pieno la General Public License (GPL) del movimento GNU Open Source.

Grazie all'aumento esponenziale dell'interesse da parte della comunità mondiale nascono i primi LUGs (Linux User Groups), ormai diffusi anche in Italia.

1995 Compaiono sul mercato delle nuove distribuzione commerciali come Caldera Linux. Kernel 1.2 in Marzo.

Dal kernel 1.3 in sviluppo si passerà direttamente al 2.0 1996 Rilasciata la versione 2.0.

Compaiono le prime versioni tradotte in più lingue.

Linux ha bisogno di una mascotte: nasce TUX, il pinguino più famoso del mondo.

(12)

1997 Da qui in poi la storia di Linux diventa sempre più Linus indipendente, nel 1997 lascia la Finlandia per raggiungere Santa Clara, Silicon Valley, dove lo aspetta, nella misteriosa start-up Transmeta, un ruolo che ai più non è chiaro.

Per anni, prima di annunciare al pubblico di produrre microprocessori a basso consumo e quotarsi al NASDAQ, Transmeta rimane un segreto impenetrabile intorno al quale si accumulano rumours e misteri:

- E' la società dove lavora Linus Torvalds (che continua a sviluppare Linux e non si capisce per cosa venga pagato)

- Fra i soci finanziatori figura Paul Allen (Microsoft co-founder) - Assume programmatori e tecnici di altissimo livello

- Sfoggia per anni una home page che è un capolavoro di anti-marketing.

1999 Dopo lunga attesa il kernel 2.2 vede la luce.

2001 Agli inizi dell'anno, dopo varie pre-version, su kernel.org appare l'immagine da 19.788.626 byte del 2.4.0 La prima release di un altro stable thread.

2002 - Linux è una reale alternativa al mondo Microsoft e Unix, si ritrova milioni di utenti, migliaia di sviluppatori e un mercato in espansione.

E' presente in sistemi integrati, è usato per il controllo di dispositivi robotizzati e ha volato a bordo dello Shuttle, praticamente gira su oggetti elettronici di tutti i tipi, dai palmari alle workstation Alpha, risultando l'OS in assoluto il sistema operativo più soggetto a porting.

Nessuno ormai si sogna di considerarlo un progetto sperimentale che non possa essere usato in applicazioni mission-critical, IBM "lo monta sui suoi server" (e lo pubblicizza pure), Microsoft lo considera il principale nemico da combattere (e non lesina risorse nel farlo), Oracle ci fa girare sopra il suo DB.

2003 - Le guerre si combattono per il petrolio e, più sotterraneamente, per il controllo dei computer. Il 2003 sarà ricordato anche per l'anno di SCO e dei suoi attacchi a Linux e al mondo OpenSource, consequenziali ad una azione legale intrapresa contro IBM.

Le modalità degli attacchi, la loro natura, il modo con cui si cerca creare FUD intorno a Linux (Fear Uncertainty and Doubt) sono sintomo di interessi che vanno oltre la protezione di presunte proprietà intellettuali per parti di codice che vengono nominate ma non mostrate sembrano delinearsi come un banco di prova decisivo per la definitiva affermazione di Linux anche sul lato desktop e per un cambio

paradigmatico su come viene valorizzato e diffuso il software.

Tecnologicamente la strada è chiara e le carte sono vincenti: Linux e tutto il software OpenSource sono decisamente all'altezza sia sui sistemi di fascia alta che sui desktop, oltre ad essere presente nel cuore invisibile di innumerevoli device elettronici.

2004 - Sgonfiato, anche se non concluso, il caso SCO, nuove minacce si profilano all'orizzonte di un

pinguino che continua a diffondersi e conquistare nuovi territori: in particolare leggi draconiane sui brevetti,

(13)

che permettono di brevettare indiscriminatamente algoritmi, soluzioni e idee informatiche triviali e ampiamente diffuse, o soluzioni tecniche tali da rendere impossibile o soggetta a una fee arbitraria l'interoperabilità fra sistemi operativi.

Intanto il kernel 2.6 si diffonde e viene usato nelle principali distribuzioni, sempre più user friendly e pronte per il desktop. E' una guerra, più o meno dichiarata, i cui i nemici spesso mostrano una faccia sorridente e colpiscono su campi e livelli che non hanno nulla a che vedere con l'innovazione e l'eccellenza tecnica.

(14)

Il progetto GNU e la Free Software Foundation

Linux deve la sua esistenza allo sforzo cooperativo di un gran numero di persone. Lo stesso nucleo del sistema operativo forma solo una piccola parte di un sistema di sviluppo utilizzabile. I sistemi UNIX commerciali tradizionalmente vengono venduti insieme a programmi applicativi che forni- scono strumenti e servizi di sistema. Per i sistemi Linux, questi programmi aggiuntivi sono stati scritti da tanti programmatori diversi e sono stati liberamente distribuiti.

La comunità Linux (insieme ad altre) supporta il concetto di free software, cioè software che sia li- bero da restrizioni, soggetto alla licenza GNU General Public License. Sebbene ci possa essere un costo per ottenere il software

3

, successivamente esso può essere usato in qualsiasi modo si desideri, e normalmente viene distribuito in formato sorgente.

La Free Software Foundation fu creata da Richard Stallman, l'autore di GNU Emacs, uno dei più conosciuti editor per UNIX ed altri sistemi. Stallman è un pioniere del concetto di free software e cominciò il progetto GNU, un tentativo di creare un sistema operativo ed ambiente di sviluppo che sarà compatibile con UNIX. Il nome GNU sta per GNU's Not Unix.

3 Costo dovuto alle spese per la sua distribuzione

(15)

La Shell

La shell

4

è l'interprete dei comandi proprio dei sistemi Unix, un programma, cioè, che legge ed interpreta i comandi che vengono inseriti dall'utente.

La sua esecuzione comincia dopo il completamento da parte dell'utente delle procedure di login;

scrive un prompt

5

(di solito uno dei due caratteri '$' o '%'), si mette in attesa di un comando, lo esegue e torna in attesa di un nuovo comando, fino a che l' utente non termina la sessione.

L' utente può interagire con la shell secondo tre modalità:

- interattiva: quando richiama i comandi del sistema.

- di programmazione: quando crea nuove sequenze di comandi attraverso frasi e variabili proprie della shell stessa.

- di personalizzazione del proprio ambiente operativo: quando predispone i files di inizializzazione e terminazione delle sessioni di lavoro, o le variabili utilizzate dai programmi di sistema.

4 La shell è una utilità che abilita l'utente ad interagire con il sistema operativo UNIX. I comandi introdotti dall'utente sono passati dalla shell al sistema operativo, che li esegue. I risultati sono poi ripassati dalla shell e visualizzati sullo schermo dell'utente.

5 È il carattere (o l'insieme di caratteri) all'inizio della riga di comando che indica che il computer (la shell) è pronto a ricevere ed eseguire un comando. Il carattere di solito è un '%' (segno percentuale) o un $ (segno di dollaro).

(16)

La shell ed il sistema operativo

In informatica, una shell è un pezzo di software che essenzialmente fornisce una specie di interfaccia per gli utenti finali. Tipicamente, il termine si riferisce alla shell di un sistema operativo che fornisce l'accesso ai servizi di un kernel. Comunque, il termine viene anche utilizzato in maniera lasca alle applicazioni e può includere qualsiasi software che sia costituito "attorno ad" un componente particolare come i browser web ed i clienti di posta elettronica, che sono "shell" per i motori di rendering dell'HTML

6

. Il nome 'shell' origina da shell essendo uno strato esterno tra l'utente e le parti interne di un sistema operativo (il kernel).

Le shell di un sistema operativo ricadono generalmente in due categorie: riga di comando e grafica.

Le shell a riga di comando forniscono una interfaccia a riga di comando (CLI: Command line interface) al sistema operativo, mentre le shell grafiche forniscono una interfaccia grafica utente (GUI: graphical user interface).

I meriti relativi delle shell CLI e delle shell basate su GUI sono spesso soggetto di dibattiti. I fautori di CLI reclamano che certe operazioni possono essere eseguite molto più velocemente sotto shell di testo (CLI), come spostare file, ad esempio, che sotto shell GUI.

Comunque, i fautori delle GUI insistono sulla facilità ed usabilità delle shell grafiche (GUI).

6 Hyper Text Markup Language

(17)

La scelta migliore è spesso determinata dal modo in cui un computer sarà usato. Su un server, usato

principalmente per l'elaborazione ed il trasferimento dei dati con una amministrazione esperta, una

CLI probabilmente è la scelta migliore. Dall'altro lato, un sistema grafico (GUI) probabilmente

sarebbe più appropriato per un computer da usare per l'elaborazione grafica o video.

(18)

Tipi di shell

Così come la gente conosce differenti linguaggi e dialetti, così un sistema UNIX offrirà usualmente una varietà di tipi di shell:

1. sh o Bourne Shell: la shell originale ancora usata sui sistemi UNIX e negli ambienti corre- lati ad UNIX. Questa è la shell di base, un piccolo programma con poche caratteristiche. An- che se non è la shell standard, è ancora disponibile su ogni sistema Linux per compatibilità con i programmi UNIX.

2. bash o Bourne Again shell: la shell standard del sistema GNU, intuitiva e flessibile. Proba- bilmente consigliabile per gli utenti alle prime armi anche se allo stesso tempo è uno stru- mento potente per l'utente avanzato e professionista. Su Linux, bash è la shell di riferimento per i comuni utenti. Questa shell è un superset della shell di Bourne, un insieme di add-on e plug-in. Questo significa che bash (Bourne Again shell) è compatibile con la shell di Bour- ne: i comandi che funzionano in sh, funzionano anche in bash. Comunque, non è sempre vero il contrario.

3. csh o C shell: la sintassi di questa shell somiglia a quella del linguaggio C.

4. tcsh o Turbo C shell: un superset della comune C shell, che migliora la facilità d'uso (user- friendliness) e la velocità.

5. ksh o Korn shell: a volte apprezzata dalle persone con una preparazione di UNIX. Un su-

perset della shell di Bourne; un incubo per gli utenti alle prime armi.

(19)

Shell come interprete di comandi

Nella sua funzione più comune la shell agisce come interprete di comandi semplici, cioè di comandi costituiti di una o più parole separate da spazi, delle quali la prima specifica il comando da eseguire, le altre se presenti sono passate come argomenti al comando.

La shell riconosce però alcuni caratteri particolari detti metacaratteri che non sono passati inaltera- ti al comando, ma che essa stessa riconosce come richieste di attivazione di modalità operative par- ticolari.

L' esecuzione di un comando in background, ad esempio, viene attivata concludendo il comando con il metacarattere &: in questo caso la shell manda in esecuzione l'istruzione "ripulita" da &, in quanto lo scopo del metacarattere era quello di comunicare alla shell di attivare l' esecuzione in background.

L' interazione tra shell e comando richiesto si conclude con la restituzione, da parte di quest'ultimo, del valore numerico zero in caso positivo, e di un valore diverso da zero in caso di fallimento.

Attivazione della shell

Come si attiva la shell? Se ci troviamo in ambiente grafico (KDE, ad esempio), sul pannello, nella parte inferiore dello schermo, clicchiamo sull'icona del terminale:

Quello che viene attivato è il programma Konsole, un emulatore di terminale in ambiente grafico X- Windows.

Terminale

(20)

I sistemi operativi UNIX in origine erano progettati come sistemi solo testo, non esistevano ancora le interfacce grafiche odierne, ed erano controllati da comando della tastiera – quello che si chiama interfaccia a riga di comando (CLI, ovvero Command-Line Interface).

Il sistema X Window, KDE ed altri progetti hanno aggiunto l'interfaccia grafica che usiamo oggi-

giorno. Ad ogni modo, il sottostante sistema CLI è ancora al suo posto ed è il modo più facile, velo-

ce e potente di eseguire molti compiti. Il programma Konsole è ciò che è conosciuto con il nome di

emulatore di terminale X, al quale ci si riferisce spesso come terminale o shell.

(21)

Input/Output standard e redirezione dell'I/O

Standard Input e Standard Output

Molti dei comandi UNIX ricevono l'input dal terminale ed inviano il risultante output indietro al terminale.

Un comando normalmente legge il suo input da un posto chiamato standard input, che per default è il terminale. In modo simile, un comando normalmente scrive il suo output sullo standard output, che per default è sempre il terminale.

Figura : Tipica esecuzione di un comando UNIX

Il comando who, ad esempio, visualizza gli utenti attualmente connessi. Più formalmente, il

comando who scrive sullo standard output (che sarebbe lo schermo) la lista degli utenti connessi.

(22)

In un programma scritto in C, le istruzioni di lettura, come ad esempio scanf, gets, ecc. si riferiscono alla tastiera come allo standard input, e le istruzioni di scrittura, ad esempio printf, puts, ecc. si riferiscono allo schermo come standard output.

In Linux (e nel linguaggio di programmazione C) la tastiera, lo schermo, ecc. sono tutti trattati come file. Nella tabella che segue ci sono i nomi di tali file.

Per default, in Linux ogni programma ha associato con esso almeno tre file, (quando facciamo eseguire un programma, questi tre file sono automaticamente aperti dalla shell in uso).

Standard File File Descriptors number Uso Esempio

stdin 0 come Standard input Keyboard

stdout 1 come Standard output Video

stderr 2 come Standard error Video

(23)

Programmazione della shell

Perché programmare la shell?

La conoscenza pratica dello scripting di shell è essenziale per coloro che desiderano diventare degli amministratori di sistema esperti, anche se mai avrebbero messo in preventivo di scrivere degli script. Occorre tener presente che quando viene avviata una macchina Linux, questa esegue gli script di shell contenuti nel file /etc/rc.d per ripristinare la configurazione del sistema ed attivarne i servizi. La comprensione dettagliata degli script di avvio è importante per analizzare il comportamento di un sistema e, se possibile, modificarlo.

Perché apprendere la Shell?

Il progettista di un programma che fornisce una interfaccia utente grafica (GUI) deve anticipare tutti i possibili modi in cui l'utente interagirà con il programma e fornisce i modi per catturare le appropriate risposte del programma a causa del puntare e cliccare. Conseguentemente, l'utente è costretto a lavorare solo nei modi previsti. L'utente perciò è incapace di adattare l'interfaccia del programma per risolvere circostanze non previste. In poche parole, è questa la ragione per cui molti compiti degli amministratori di sistema sono svolti usando la shell: gli amministratori di sistema, nell'adempiere alle proprie responsabilità di mantenere un sistema funzionante, devono continuamente trattare con e vincere l'imprevisto.

Imparare a scrivere degli script non è difficile, perché possono essere costituiti da sezioni di piccole dimensioni ed è veramente esigua anche la serie di operatori ed opzioni specifiche che è necessario conoscere. La sintassi è semplice e chiara, come quella necessaria per eseguire e concatenare utilità da riga di comando, e sono poche anche le "regole" da imparare. Nella maggior parte dei casi, gli script di piccole dimensioni funzionano correttamente fin dalla prima volta che vengono eseguiti e non è complicata neanche la fase di debugging di quelli di dimensioni maggiori.

Uno script di shell è un metodo "rapido e grezzo" per costruire un prototipo di un'applicazione complessa. Far eseguire anche una serie ridotta di funzionalità tramite uno script di shell è spesso un utile primo passo nello sviluppo di un progetto. In questo modo si può verificare e sperimentare la struttura di un'applicazione e scoprire i principali errori prima di procedere alla codifica finale in C, C++, Java o Perl.

Lo scripting di shell è attento alla filosofia classica UNIX di suddividere progetti complessi in

(24)

sezioni di minori dimensioni che svolgono un compito particolare, concatenando componenti e utilità Questo è considerato, da molti, un approccio migliore, o almeno esteticamente più piacevole per risolvere un problema, che utilizzare uno dei linguaggi di nuova generazione , come Perl, che offrono funzionalità per ogni esigenza, ma al prezzo di costringere a modificare il modo di pensare un progetto per adattarlo al linguaggio utilizzato.

Quando non usare gli script di shell

-In compiti che richiedono un utilizzo intenso di risorse, specialmente quando la velocità è un fattore determinante (ordinamenti, hashing, ecc.)

-In procedure che comprendono operazioni matematiche complesse, specialmente aritmetica in virgola mobile, calcoli in precisione arbitraria o numeri complessi (si usi C++ o FORTRAN)

È necessaria la portabilità (si usi, invece, il C o Java)

- In applicazioni complesse dove è necessaria la programmazione strutturata (necessità di tipizzazione delle variabili, prototipi di funzione, ecc.)

- In applicazioni particolari su cui si sta rischiando il tutto per tutto, o il futuro della propria azienda

In situazioni in cui la sicurezza è importante, dove occorre garantire l'integrità del sistema e proteggerlo contro intrusioni, cracking e vandalismi

In progetti costituiti da sotto-componenti con dipendenze interconnesse

Sono richieste operazioni su file di grandi dimensioni (Bash si limita ad un accesso sequenziale ai file, eseguito riga per riga e in un modo particolarmente goffo ed inefficiente)

E' necessario il supporto nativo per gli array multidimensionali

Sono necessarie strutture di dati quali le liste collegate o gli alberi

E' necessario generare o manipolare grafici o GUI

È necessario un accesso diretto all'hardware del sistema

È necessaria una porta o un socket I/O

È necessario l'utilizzo di librerie o interfacce per l'esecuzione di vecchio codice

In applicazioni proprietarie a codice chiuso (il codice sorgente degli script di shell è aperto e

tutti lo possono esaminare)

(25)

Che cos'è uno script di shell ?

* Un file di testo contenente comandi che avrebbero potuto essere scritti direttamente nella shell.

* La stessa shell ha limitate capacità -- la sua potenza deriva dall'usarla come linguaggio collante per combinare i comandi standard di Unix ed il software dell'utente, per produrre uno strumento più utile che i componenti presi da soli.

* Una qualsiasi shell può essere utilizzata per scrivere uno script di shell. Per fare ciò, la prima riga di ogni script deve essere:

#!/percorso/alla/shell

ad esempio

#!/bin/bash

* Qualsiasi file può essere usato come input della shell usando la sintassi:

bash mioscript

Se il file è reso eseguibile usando il comando chmod, esso diventa un nuovo comando e disponibile all'uso

Esempio:

chmod +x mioscript

Uno script di shell può essere tanto semplice come una sequenza di comandi che scriviamo

regolarmente. Mettendoli in uno script, li riduciamo ad un singolo comando

(26)

Gli operatori aritmetici e relazionali della shell Bash

Gli operatori aritmetici che si possono usare nella shell sono i seguenti:

- operando inverte il segno dell'operando

operando1 + operando2 somma i due operandi

operando1 - operando2 differenza tra i due operandi

operando1 * operando2 prodotto tra i due operandi

operando1 / operando2 divisione intera tra i due operandi

operando1 % operando2 calcola il modulo, cioè il resto della divisione tra il primo ed il secondo operando

Gli operatori relazionali che si possono usare nella shell sono i seguenti:

-lt (abbreviazione di less than) equivale al test <

Es. a -lt b verifica se a < b

-gt (abbreviazione di greater than) equivale al test >

Es. a -gt b verifica se a>b

-le (abbreviazione di less than or equal to) equivale al test <=

Es. a -le b verifica se a<=b

-ge (abbreviazione di greater than or equal to) equivale al test >=

Es. a -ge b verifica se a>=b

-eq (abbreviazione di equal to) equivale al test ==

Es. a -eq b verifica se a==b

-ne (abbreviazione di not equal to) equivale al test !=

Es. a -ne b verifica se a!=b

(27)

Programmazione della shell: le strutture di ripetizione

Nella shell di Bash abbiamo a disposizione varie strutture di ripetizione, che sono implementate attraverso i seguenti costrutti:

-while -until -for

Il ciclo while

La sintassi della struttura while ha il seguente formato:

while [ condizione ] do

comandi/istruzioni done

Il ciclo while permette di ripetere tutti i comandi o le istruzioni comprese tra do e done finché la condizione specificata tra le parentesi quadre rimane verificata, ovvero mantiene il valore logico vero.

Affinché il ciclo abbia termine, la condizione ad un certo punto non deve essere più verificata.

Esempio:

#!/bin/bash

# Ciclo infinito i=0

while [ $i -eq 0 ] do

echo $i

done

(28)

Questo ciclo non termina mai. Per interrompere l'esecuzione, usiamo la combinazione di tasti CTRL+c

Il ciclo seguente invece termina subito dopo aver stampato il valore della variabile i:

#!/bin/bash

# Ciclo finito i=0

while [ $i -eq 0 ] do

echo $i i=1 done

Attenzione! La condizione tra le parentesi quadre deve essere scritta lasciando uno spazio a destra ed uno spazio a sinistra.

Ad esempio:

#!/bin/bash

# Ciclo infinito i=0

while [$i -eq 0]

do echo $i done

se facciamo eseguire questo script otteniamo il seguente messaggio di errore:

[0: command not found

(29)

Esercizio

Stampare i primi 10 numeri naturali 1, 2, 3, 4, 5, 6, 7, 8, 9 10

Vediamo di applicare quanto spiegato sui cicli di while per risolvere il seguente semplicissimo problema: stampare i primi 10 numeri naturali 1, 2, 3, 4, 5, 6, 7, 8, 9 10

Abbiamo già risolto il problema usando il linguaggio C, e quindi l'algoritmo non dovrebbe essere del tutto sconosciuto, oltre ad essere anche banale. Veniamo al dunque. Quello che ci serve è una variabile, diciamo i, che parte da 1 ed arriva a 10, stampata e poi incrementata man mano.

#!/bin/bash

# Inizializziamo la variabile contatore i i=1

la condizione da verificare è i<=10, che scriveremo come:

$i -le 10

Partiamo poi ad eseguire il ciclo

while [ $i -le 10 ] do

Stampiamo il contenuto della variabile i:

echo $i

Incrementiamo la variabile i:

let i=$(($i+1))

(30)

done

Ecco lo script completo

#!/bin/bash i=1

while [ $i -le 10 ] do

echo $i

let i=$(($i+1)) done

Scriviamo con un editor di testo lo script, lo salviamo con il nome ciclo_stampa.sh, impostiamo poi i permessi di esecuzione con

chmod u+x ciclo_stampa.sh

e lo mandiamo in esecuzione con ./ciclo_stampa.sh

(31)

ESERCIZIO

L'esercizio che svolgeremo ora è una piccola modifica dell'esercizio precedente, e cioè stampare i primi N numeri naturali 1, 2, 3, ..., N, dove però l'ultimo numero da stampare è variabile. Invece nell'esercizio precedente era sempre fissato a 10.

Useremo una seconda variabile, N, dove memorizziamo l'estremo superiore della sequenza da stampare.

Come abbiamo già detto, l'algoritmo non dovrebbe essere del tutto sconosciuto, oltre ad essere anche banale. Veniamo al dunque. Quello che ci serve è una variabile, diciamo i, che parte da 1 ed arriva a N, stampata e poi incrementata man mano.

In questa versione Inizializziamo N ad un valore a scelta, ad esempio N=15

#!/bin/bash

# Inizializziamo la variabile contatore i

i=1

(32)

# Inizializziamo la variabile N N=15

la condizione da verificare è i<=N, che scriveremo come:

$i -le N

Partiamo poi ad eseguire il ciclo while [ $i -le $N ]

do

Stampiamo il contenuto della variabile i:

echo $i

Incrementiamo la variabile i:

let i=$(($i+1)) done

Ecco lo script completo

#!/bin/bash i=1

N=15

while [ $i -le $N ] do

echo

7

$i let i=$(($i+1)) done

Scriviamo con un editor di testo lo script, lo salviamo con il nome ciclo_stampa2.sh, impostiamo poi i permessi di esecuzione con

chmod u+x ciclo_stampa2.sh

e lo mandiamo in esecuzione con ./ciclo_stampa2.sh

7 Il comando echo visualizza un messaggio sullo schermo, inviando ogni stringa allo standard output, eterminandocon un newline

(33)

Visualizzare l'output: il comando echo

Negli esercizi precedenti abbiamo iniziato ad usare il comando echo. Il comando visualizza un messaggio sullo schermo, inviando ogni stringa allo standard output, e terminando con un newline.

Ad esempio, il comando echo pere mele banane

visualizza sullo schermo le tre parole pere mele banane

Ma il comando echo è molto più potente ed ha varie opzioni che arricchiscono la sua funzionalità.

Supponiamo ad esempio di voler sopprimere il newline

8

. Consideriamo il seguente script che stampa sul video la tabellina pitagorica:

#!/bin/bash

#Tabellina pitagorica i=1

8 Carattere speciale per stampare su una nuova riga

(34)

while [ $i -le 10 ] do

j=1

while [ $j -le 10 ] do

#calcola il prodotto i*j let p=$(($i*$j))

#stampa il prodotto i*j echo $p

#incrementa la variabile j let j=$(($j+1))

done

#incrementa la variabile i let i=$(($i+1))

#stampa una nuova riga echo

done

Se usiamo il comando echo nella sua forma più semplice, senza alcuna opzione, non potremo evitare che ogni numero venga stampato su una riga diversa, quindi avremo la tabellina stampata su 100 righe!

Per evitare che il comando echo stampi ogni dato su una riga diversa, dobbiamo sopprimere l'emissione della nuova riga ogni volta che viene inviato sull'output standard un nuovo dato. Cioè, dobbiamo stampare tutti i dati su una stessa riga.

L'opzione -n aggiunta al comando echo evita di eseguire un newline alla fine della stampa.

Modifichiamo allora il nostro script.

#!/bin/bash

#Tabellina pitagorica i=1

while [ $i -le 10 ] do

j=1

while [ $j -le 10 ] do

let p=$(($i*$j)) echo -n $p let j=$(($j+1)) done

let i=$(($i+1)) echo

done

E vediamo l'output di questo nuovo script:

12345678910

(35)

2468101214161820 36912151821242730 481216202428323640 5101520253035404550 612182430ù3642485460 7142128354249566370 8162432404856647280 9182736455463728190 102030405060708090100

Un poco disordinato! Cerchiamo di separare i numeri. Aggiungiamo uno spazio vuoto trai numeri:

#!/bin/bash

#Tabellina pitagorica i=1

while [ $i -le 10 ] do

j=1

while [ $j -le 10 ] do

let p=$(($i*$j)) echo -n " " $p let j=$(($j+1)) done

let i=$(($i+1)) echo

done

Vediamo il risultato dell'esecuzione dello script:

1 2 3 4 5 6 7 8 9 10 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20 24 28 32 36 40 5 10 15 20 25 30 35 40 45 50 6 12 18 24 30 36 42 48 54 60 7 14 21 28 35 42 49 56 63 70 8 16 24 32 40 48 56 64 72 80 9 18 27 36 45 54 63 72 81 90 10 20 30 40 50 60 70 80 90 100

Ci vorrebbe un'opzione per poter distanziare i numeri. Bisognerebbe poter aggiungere un carattere di tab dopo ogni numero. Il comando echo permette di usare il carattere di tabulazione '\t', ma bisogna abilitarlo, con l'opzione -e

Ovvero il comando echo si scriverà come:

echo -ne dato da visualizzare

Ecco come modificheremo il nostro script

(36)

#!/bin/bash

#Tabellina pitagorica i=1

while [ $i -le 10 ] do

j=1

while [ $j -le 10 ] do

let p=$(($i*$j)) echo -ne '\t' $p let j=$(($j+1)) done

let i=$(($i+1)) echo

done

Ed ecco l'output ottenuto dall'esecuzione dello script:

1 2 3 4 5 6 7 8 9 10

2 4 6 8 10 12 14 16 18 20

3 6 9 12 15 18 21 24 27 30

4 8 12 16 20 24 28 32 36 40

5 10 15 20 25 30 35 40 45 50

6 12 18 24 30 36 42 48 54 60

7 14 21 28 35 42 49 56 63 70

8 16 24 32 40 48 56 64 72 80

9 18 27 36 45 54 63 72 81 90

10 20 30 40 50 60 70 80 90 100

Ed è proprio quello che volevamo!

(37)

Il ciclo while e il ciclo di for

Essenzialmente esistono due tipi di cicli (strutture iterative):

-ciclo while -ciclo for

La sintassi del ciclo while è la seguente:

while [ condizione ] do

istruzioni done

Attenzione! Lasciare uno spazio tra while e la prima parentesi quadra ed all'interno della parentesi quadra, uno spazio prima e dopo la condizione.

La sintassi del ciclo for è la seguente:

for dato in Lista do

istruzioni done

Il ciclo di for nella shell BASH è completamente diverso dal ciclo di for del linguaggio C. Durante ogni passo attraverso il ciclo, la variabile dato prende il valore di ogni variabile presente nella lista.

La lista può essere un elenco qualsiasi, un array, un elenco di stringhe, un elenco di variabili, ecc.

Esempio 1

#!/bin/bash

for giorno in "Lunedì","Martedì","Mercoledì","Giovedì","Venerdì","Sabato","Domenica"

do

echo "Oggi è "$giorno done

Lo stesso ciclo di prima, ma scritto in modo differente. Eseguite i due script, e annotate le differenze.

Esempio 2

#!/bin/bash

for giorno in Lunedì Martedì Mercoledì Giovedì Venerdì Sabato Domenica

do

(38)

echo "Oggi è "$giorno done

Esempio 3

#!/bin/bash

#pianeti.sh

#Visualizza l'elenco dei pianeti del sistema solare echo "I pianeti del sistema solare"

for pianeta in Mercurio Venere Terra Marte Giove Saturno Uranio Nettuno Plutone do

echo $pianeta done

La lista può anche essere un array:

#!/bin/bash

#pianeti.sh

#Visualizza l'elenco dei pianeti del sistema solare declare -a pianeti

echo "I pianeti del sistema solare"

pianeti=( Mercurio Venere Terra Marte Giove Saturno Uranio Nettuno Plutone ) for pianeta in ${pianeti[*]}

do

echo $pianeta done

Ricordiamo che per riferirci a tutto il contenuto di un array, scriveremo sempre:

${nome_array[*]}

nel nostro caso:

${pianeti[*]}

Il ciclo While

Il ciclo while permette di ripetere tutti i comandi o le istruzioni comprese tra do e done finché la condizione specificata tra le parentesi quadre rimane verificata, ovvero mantiene il valore logico vero.

Affinché il ciclo abbia termine, la condizione ad un certo punto non deve essere più verificata.

Esempio:

(39)

#!/bin/bash

# Ciclo infinito i=0

while [ $i -eq 0 ] do

echo $i done

Questo ciclo non termina mai. Per interrompere l'esecuzione, usiamo la combinazione di tasti CTRL+c

Il ciclo seguente invece termina subito dopo aver stampato il valore della variabile i:

#!/bin/bash

# Ciclo finito i=0

while [ $i -eq 0 ] do

echo $i i=1 done

Attenzione! La condizione tra le parentesi quadre deve essere scritta lasciando uno spazio a destra ed uno spazio a sinistra.

Ad esempio:

#!/bin/bash

# Ciclo infinito i=0 while [$i -eq 0]

do echo $i done

se facciamo eseguire questo script otteniamo il seguente messaggio di errore:

[0: command not found

Esercizio di programmazione in bash: verifica se un'equazione di secondo grado ha radici reali o complesse e coniugate

Da notare come si eseguono le operazioni aritmetiche. In bash si usa una tecnica particolare. Tutta

l'espressione deve essere racchiusa da una doppia coppia di parentesi, il tutto preceduto dal segno di

(40)

dollaro ($). Ad esempio:

# Assegna i valori alle variabili a e b a=1

b=2

# Calcola l'espressione $a+$b e l'assegna alla variabile c let c=$(($a+$b))

# Visualizza il contenuto della variabile c echo $c

Listato dello script risolvi.sh

#!/bin/bash

#Nome Script: risolvi.sh

#Scopo: Verifica se un'equazione di secondo grado ha radici reali o complesse e coniugate

#Uso ./risolvi.sh A B C

#Es. ./risolvi.sh 1 2 1 declare A

declare B declare C declare Delta

# Lettura degli argomenti dalla riga di comando A=$1

B=$2 C=$3

#Stampa di prova degli argomenti letti echo A=$A

echo B=$B echo C=$C

#Stampa di prova del valore calcolato di Delta let Delta=$(($B*$B-4*$A*$C))

echo Delta=$Delta if [ $Delta -ge 0 ] then

echo "Radici reali e distinte"

else

echo "Radici complesse e coniugate"

fi

(41)

Le variabili di sistema

Parliamo di alcune variabili di sistema che assumono un ruolo particolare, diciamo speciale, nell'ambito della shell.

La shell possiede queste variabili speciali:

$#

$*

$?

$$

La variabile $#

La variabile $# rappresenta il numero dei parametri opzionali passati come argomento allo script.

La variabile $*

La variabile speciale $* rappresenta la lista dei parametri opzionali passati come argomento allo script.

La variabile $?

La variabile $?, seguita dal nome del comando, serve per determinare lo stato di uscita dall'ultimo comando eseguito dalla shell. Se il risultato è 0 significa che il comando si è concluso

correttamente, un valore diverso da zero indica che il comando si è concluso con una situazione di errore.

La variabile $$

La variabile $$ rappresenta il PID (Process IDentifier) del processo della shell, processo padre del

comando in esecuzione.

(42)

Lettura dei dati: l'istruzione read

L'istruzione read è una istruzione interna di bash, e come è facile intuire, serve per la lettura dei dati dal dispositivo standard di input (che in genere è la tastiera, ma questa situazione di default può essere cambiata). Nella sua forma più semplice l'istruzione read usa la seguente sintassi:

read variabile

ovvero assegna alla variabile il valore letto dal dispositivo standard di input (la tastiera).

Ad esempio, proviamo il codice seguente:

#!/bin/bash

# script1.sh echo "input a1: "

read a1

echo "input a2: "

read a2

echo "a1 = " $a1 echo "a2 = " $a2

Lo script precedente legge prima la variabile tramite l'istruzione read a1 e poi legge la variabile a2 tramite l'istruzione read a2. Infine visualizza le due variabili sul dispositivo standard di output (lo schermo, in genere)

echo "a1 = " $a1

echo "a2 = " $a2

(43)
(44)

Fornire i comandi alla Shell

Quando la shell viene eseguita, visualizza un prompt sul terminale, di solito un segno di dollaro $, ed attende che l'utente scriva un comando.

Ogni volta che l'utente inserisce il comando e preme il tasto INVIO, la shell analizza la riga inserita

e la processa per completare la richiesta. Se l'utente chiede di eseguire un particolare programma, la

shell ricerca sul disco finché non trova il programma invocato. Quando l'ha trovato, la shell chiede

al kernel di iniziare l'esecuzione del programma, e poi la shell “si mette a dormire” finché

l'esecuzione del programma non è terminata. Il kernel copia in memoria il programma specificato e

comincia la sua esecuzione. Il programma copiato in memoria si chiama processo; in questo modo,

viene fatta una distinzione tra il programma registrato in un file su disco ed un processo che si trova

in esecuzione in memoria.

(45)

Filesystem di Linux

Un filesystem comprende i metodi e le strutture dei dati usate da un sistema operativo per tenere traccia dei file su un hard disk o su una sua partizione, cioè il modo in cui i file sono organizzati sui dischi. La parola viene anche usata per riferirsi ad una partizione o a un disco usato per immagazzinare i file, o al tipo del filesystem stesso.

Prima che si possa usare un disco o una partizione come filesystem, questo deve essere inizializzato e bisogna scriverci le strutture di dati per l'archiviazione: questo processo si chiama creazione di un filesystem .

Un singolo hard disk può essere diviso in diverse partizioni, ciascuna delle quali funziona come se fosse un disco separato. L'idea è che se avete un hard disk e ad esempio volete avere due sistemi operativi, potete suddividere il disco in due partizioni; ciascun sistema operativo userà la sua partizione come vuole e non toccherà quella dell'altro.

In questo modo i due sistemi possono coesistere sullo stesso hard disk, mentre senza le partizioni ci sarebbe voluto un disco per ciascun sistema operativo.

I floppy non vengono partizionati, non per motivi tecnici, ma perché sono molto piccoli e creare al loro interno delle partizioni non sarebbe utile se non in casi molto rari. I CD-ROM di solito non vengono partizionati, dato che è molto più semplice usarli come un grande disco e in genere non è necessario avere diversi sistemi operativi sullo stesso CD-ROM.

L'MBR, i settori di boot e la tabella delle partizioni

Le informazioni sul partizionamento di un hard disk si trovano nel suo primo settore. Questo settore si chiama master boot record (MBR ) del disco.

L'MBR è il settore che il BIOS legge ed avvia quando la macchina viene accesa. Il master boot record contiene un piccolo programma che legge la tabella delle partizioni , controlla quale partizione è attiva (cioè quale è contrassegnata come avviabile) e legge il primo settore di quella partizione, il boot sector (settore di avvio ) della partizione (anche l'MBR è un settore di avvio, ma ha uno status speciale e quindi un nome speciale).

Il boot sector contiene un altro programmino che legge la prima parte del sistema operativo

(46)

contenuto in quella partizione (sempre che sia avviabile) e lo avvia.

Il BIOS

BIOS (pronunciato / ba o s/), è l'abbreviazione di Basic Input/Output System. ˈ ɪ ʊ

Il termine è scorrettamente conosciuto come “Binary Input/Output System”, “Basic Integrated Operating System” ed occasionalmente “Built In Operating System”. BIOS si riferisce al codice del firmware eseguito da un personal computer all'accensione. La funzione primaria del BIOS è di identificare ed inizializzare i componenti hardware, (come gli hard drive, floppy, e CD). Questo serve a preparare la macchina in modo tale che altri programmi memorizzati su mezzi diversi possano caricare, eseguire ed assumere il controllo del PC. Questo processo è noto come booting, o booting up, che è l'abbreviazione di bootstrapping.

BIOS si può anche dire di un programma codificato inserito su un chip che riconosce e controlla vari dispositivi che costituiscono un personal computer. Tra le altre classi di computer, erano comunemente usati i termini boot monitor, boot loader o boot ROM.

Il termine BIOS è comparso per la prima volta nel sistema operativo CP/M, descrivendo la parte di CP/M caricata durante la fase di boot che si interfacciava direttamente con l'hardware (le macchine CP/M avevano generalmente un semplice boot loader nella ROM, e niente altro). Molte versioni di DOS hanno un file chiamato "IBMBIO.COM" o "IO.SYS" che è analogo al BIOS su disco di CP/M.

Come il BIOS viene caricato

Il BIOS viene caricato da PROM, EPROM o, più comunemente, da flash memory quando il computer viene acceso. Esso inizializza parecchi componenti della motherboard e periferche, tra cui:

Il generatore di clock.

I processori e le cache.

I chipset (controller della memoria ed i controller di I/O).

La memoria di sistema.

Tutti i dispositivi PCI (assegnando le risorse ed i numeri di bus).

Il controller rimario della grafica.

Controller della memoria di massa (come SATA ed i controller IDE).

Vari controller di I/O (come tastiera/mouse e USB).

(47)

Infine, carica il boot loader per il sistema operativo, e trasferisce il controllo ad esso. L'intero processo è noto come power-on self-test (POST). Sull'originario IBM PC, l'hardware necessitava solo una configurazione minimale e POST veniva usato solo per la verifica; sui sistemi moderi, la maggior parte del POST consiste in realtà di configurazione hardware.

Una volta che la memoria di sistema è inizializzata, il BIOS tipicamente copia/decomprime se stesso in quella memoria e continua l'esecuzione da esso.

Quasi tutte le implementazioni BIOS possono opzionalmente eseguire un programma di setup interfacciante la memoria non volatile del BIOS (CMOS). Questa memoria mantiene i dati di configurazione definiti dall'utente (password, ora, data, dettagli dell'hard disk, ecc.) ai quali accede il codice del BIOS. Il codice sorgente in linguaggio macchina 80x86 del BIOS per i primi PC e AT fu incluso con il manuale "IBM Personal Computer Technical Reference Manual".

Nella maggior parte delle moderne implementazioni del BIOS, l'utente decide dove il BIOS carica la sua immagine di boot: CD, hard disk, floppy disk, dispositivo USB o attraverso una connessione di rete. Ciò è particolarmente utile per installare sistemi operativi oppure fare il boot memorie flash o da LiveCD, e per selezionare l'ordine di verifica della presenza di un dispositivo avviabile.

Alcuni BIOS consentono all'utente di selezionare il sistema operativo da caricare (es. caricare un

altro sistema operativo dal secondo hard disk), sebbene questo sia più spesso gestito da un boot-

loader di secondo stadio.

(48)

Partizioni estese e partizioni logiche

Lo schema di partizionamento originale degli hard disk dei PC permetteva solo quattro partizioni, ma presto questo si è dimostrato troppo poco per l'uso reale, perché alcune persone volevano più di quattro sistemi operativi (Linux, MS-DOS, OS/2, Minix, FreeBSD, NetBSD, o Windows NT, per nominarne alcuni), ma principalmente perché a volte è una buona idea avere diverse partizioni per un solo sistema operativo.

Partizioni estese

Per superare questo problema di progettazione, furono create le partizioni estese . Questo trucco

permette di partizionare una partizione primaria in sotto-partizioni. La partizione primaria così

suddivisa si dice estesa e le sottopartizioni sono partizioni logiche: si comportano come primarie

ma vengono create in maniera diversa; non comportano una differenza di velocità

.

(49)

La struttura delle partizioni di un  hard disk

Il disco viene diviso in tre partizioni primarie, la seconda delle quali è divisa in due partizioni logiche, e parte del disco non viene partizionato. Il disco intero e ciascuna partizione primaria hanno un settore di boot.

Figura - Un esempio di partizionamento di hard disk.

(50)

Le informazioni rilevanti sulla tabella delle partizioni si ricavano dal comando fdisk -l:

[root@www padrone]# fdisk -l /dev/hda Disk /dev/hda: 81.9 GB, 81964302336 bytes 16 heads, 63 sectors/track, 158816 cylinders Units = cilindri of 1008 * 512 = 516096 bytes

Dispositivo Boot Start End Blocks Id System /dev/hda1 * 1 13990 7050928+ 83 Linux /dev/hda2 13991 158816 72992304 5 Esteso

/dev/hda5 13991 17240 1637968+ 82 Linux swap / Solaris /dev/hda6 17241 35105 9003928+ 83 Linux

/dev/hda7 35106 67505 16329568+ 83 Linux /dev/hda8 67506 108812 20818696+ 83 Linux /dev/hda9 108813 113932 2580448+ 83 Linux /dev/hda10 113933 133702 9964048+ 83 Linux /dev/hda11 133703 158816 12657424+ 83 Linux

(51)

Che cos'è una partizione ?

Il partizionamento è il mezzo per dividere un singolo hard disk in molti dischi logici. Una partizione è un insieme contiguo di blocchi su un disco che sono trattati come un disco indipendente. Una tabella delle partizioni è un indice che correla le sezioni dell'hard disk alle partizioni.

Perché avere partizioni multiple?

Incapsulare i dati. poiché la corruzione del file system è locale ad una partizione, se avviene qualche problema si perdono solo quelli della partizione.

Incrementare l'efficienza dello spazio del disco. E' possibile formattare con differenti dimensioni dei blocchi, dipendente dal vostro utilizzo. Se i vostri dati consistono di un grande numero di piccoli file (meno di 1k) e la vostra partizione usa blocchi di 4k, state sprecando 3K per ogni file. In generale, si spreca in media la metà di un blocco per ogni file, così che adattando la dimensione del blocco alla dimensione media dei vostri file è molto importante se ne avete molti.

Limitare la crescita dei dati. Processi incontrollabili oppure utenti maniacali possono consumare così tanto spazio su disco che il sistema operativo non ha più spazio sull'hard- disk per le sue operazioni di salvataggio. Ciò condurrà a dei disastri.

Dispositivi

C'è una speciale nomenclatura che linux usa per riferirsi alle partizioni dell'hard disk. In Linux, le partizioni sono rappresentate da file di dispositivi. Questi sono dei falsi file che sono localizzati in /dev. Ecco alcuni esempi:

brw-rw---- 1 root disk 3, 0 May 5 1998 hda brw-rw---- 1 root disk 8, 0 May 5 1998 sda crw--- 1 root tty 4, 64 May 5 1998 ttyS0

Un file di dispositivo è un file di tipo c ( c sta per dispositivi a "carattere", dispositivi che non usano

la memoria come cache) oppure b (per dispositivi a "blocchi", che usano la memoria cache. In

Linux, tutti i dischi sono rappresentati solo come dispositivi a blocchi.

(52)

Nomi dei dispositivi

Convezione sui nomi

Per convenzione, i dischi IDE avranno nomi che variano da /dev/hda a /dev/hdd. L'hard disk A (/dev/hda) è il primo dispositivo e hard disk C (/dev/hdc) è il terzo.

nome del 

drive controller del drive numero del drive

/dev/hda 1 1

/dev/hdb 1 2

/dev/hdc 2 1

/dev/hdd 2 2

    

    Tabella. Convenzione di denominazione dei controller IDE

Un tipico PC ha due controller IDE, ognuno dei quali ha due dischi connessi ad esso. Per esempio /dev/hda è il primo drive (master) sul primo controller IDE e /dev/hdd è il secondo drive (slave) sul secondo controller (il quarto drive IDE nel computer).

E' possibile scrivere direttamente su questi dispositivi (usando i comandi cat oppure dd).

Comunque, poiché questi dispositivi rappresentano l'intero disco, con inizio nel primo blocco, si può erroneamente sovrascrivere il master boot record e la tabella delle partizioni, il che renderà inutilizzabile il drive.

nome del 

drive controller del 

drive  numero di 

drive  tipo di 

partizione  numero di  partizione

/dev/hda1 1 1 primary 1

/dev/hda2 1 1 primary 2

/dev/hda3 1 1 primary 3

/dev/hda4 1 1 swap NA

/dev/hdb1 1 2 primary 1

/dev/hdb2 1 2 primary 2

/dev/hdb3 1 2 primary 3

/dev/hdb4 1 2 primary 4

Tabella. Nomi delle partizioni

(53)

Una volta che il drive è stato partizionato, le partizioni saranno rappresentate come numeri alla fine dei nomi. Per esempio, la seconda partizione sul secondo hard disk sarà /dev/hdb2. Il tipo di

partizione (primary) è elencata nella tabella di sopra per chiarezza.

nome del 

drive controller del 

drive numero di drive  tipo di 

partizione  numero di  partizione

/dev/sda1 1 6 primary 1

/dev/sda2 1 6 primary 2

/dev/sda3 1 6 primary 3

Tabella . Dischi SCSI

I dischi SCSI seguono uno schema simile; sono rappresentati da 'sd' invece che da 'hd'. La prima partizione del secondo disco SCSI sarebbe perciò /dev/sdb1. Nella tabella precedente, il numero di drive è arbitrariamente scelto come numero 6 per introdurre l'idea che i numeri ID SCSI non si mappano sui nomi di dispositivi sotto Linux.

Assegnazione dei nomi

Sotto (Sun) Solaris e (SGI) IRIX, il nome del dispositivo assegnato ad un drive SCSI ha qualche relazione con dove lo inserite. Sotto Linux non è così e l'assegnazione è arbitraria.

Prima

SCSI ID #2 SCSI ID #5 SCSI ID #7 SCSI ID #8 /dev/sda /dev/sdb /dev/sdc /dev/sdd

Dopo 

SCSI ID #2 SCSI ID #7 SCSI ID #8 /dev/sda /dev/sdb /dev/sdc

I drive SCSI hanno numeri ID che variano da 1 a 15. Numeri ID SCSI più bassi sono assegnati a lettere di ordine più basso. Per esempio, se avete due dischi numerati 2 e 5, allora #2 sarà /dev/sda e

#5 sarà /dev/sdb. Se li rimuovete entrambi, tutti i drive con numerazione più alta saranno

ridenominati la prossima volta che si esegue il boot

Riferimenti

Documenti correlati

Macintosh si appropria del lavoro che si trova sulla vostra scrivania ma non della vostra scrivania.. Occupa soltanto 25 x 25 cm più o meno come una

Il sistema operativo, quando c’è bisogno di eseguire un nuovo servizio (e quindi di mandare in esecuzione un nuovo processo) decide di mandarlo in esecuzione sul processore che

invece, il mutuo di scopo convenzionale è un contratto consensuale parzialmente diverso dal mutuo ordinario previsto dal codice civile data la sua diversa funzione, e

Tali indici sono stati utilizzati per molto tempo dai fornitori di piattaforme elaborative per caratterizzare le prestazioni dei propri processori; quindi vengono brevemente passati

Ogni volta che si adotta un tipo di memo- ria Flash diverso il produttore della scheda madre deve farsi carico di implementare i cambiamenti neces- sari sia all’interno del Bios

In via preliminare, occorre verificare se la richiesta di parere formulata dal Comune di Vailate presenti, alla luce dei principi elaborati dalla giurisprudenza di questa Corte

Quel 10% del tempo che al medi- co di medicina generale rimaneva da dedicare al dialogo, alla visita ed all’osservazione del suo paziente si è ulteriormente contratto e

Nella virtualizzazione parziale, inclusa cui la virtualizzazione dello spazio di indirizzamento, la macchina virtuale simula più istanze di gran parte di un