55
Sistemi Operativi Appunti del Corso di Sistemi Operativi - A.A. 2011-12 Università del Salento Luca Marzo • [email protected] 2012

Appunti del corso di Sistemi Operativi

Embed Size (px)

DESCRIPTION

Appunti del Corso di Sistemi Operativi - Università del Salento - Lezioni prof. F. Tommasi

Citation preview

Page 1: Appunti del corso di Sistemi Operativi

Sistemi Operativi Appunti del Corso di Sistemi Operativi - A.A. 2011-12 Università del Salento

Luca Marzo • [email protected]

20

12

Page 2: Appunti del corso di Sistemi Operativi

2

Introduzione Questi appunti nascono dall’esigenza di avere uno strumento unitario che raccogliesse tutti i comandi

visti nel corso delle lezioni tenute dal Prof. Franco Tommasi della Facoltà di Ingegneria, Università del

Salento.

Lungi dal sostituire un libro di testo, queste pagine hanno l’unico scopo di fornire un rapido supporto

per l’utilizzo di una serie di comandi per il terminale di Mac OS X e GNU/Linux.

Ringraziamenti È doveroso, a conclusione di questo lavoro di stesura di appunti ringraziare (in ordine sparso) le

persone che, a vario titolo, hanno contribuito alla correzione ed al miglioramento degli appunti.

Prof. Franco Tommasi

Giampiero D’Autilia

Luca De Pandis

Simone Laierno

Arianna Leverè

Giorgia Indraccolo

Alessia Cortese

Eugenia Longhin

Erica Marzo

Note e correzioni Sono graditi suggerimenti e correzioni da inviare all’indirizzo di posta [email protected]

Questi appunti sono distribuiti liberamente e sono scaricabili dal seguente link:

http://dl.dropbox.com/u/49017444/os.pdf

Gli script creati a lezione sono disponibili al seguente link:

http://dl.dropbox.com/u/49017444/os-script.zip

Page 3: Appunti del corso di Sistemi Operativi

3

Sistemi Operativi

Comando Descrizione

cd / Cambia Directory -> Root ls -la Vedi cartelle e file presenti nella cartella corrente ed i relativi dettagli cd Cambia directory (Specificare la cartella di destinazione)

Cartella Sistema Operativo Descrizione

Volumes MacOS X Mostra tutti i volumi montati sulla macchina in uso bin MacOS X - GNU/Linux Utility di sistema che non richiedono privilegi

particolari etc MacOS X - GNU/Linux Contiene file di configurazione della macchina tmp MacOS X - GNU/Linux Cartella di file temporanei usr MacOS X - GNU/Linux Contiene tutti i file/utility necessarie all'utente/i in

modalità multiuser sbin MacOS X - GNU/Linux Utility di sistema che richiedono privilegi dev MacOS X - GNU/Linux var MacOS X - GNU/Linux Contiene file soggetti a variazioni (es. logs)

Cartella Sistema Operativo Descrizione

tmp GNU/Linux File temporanei home GNU/Linux Directory in cui vengono piazzate le directory degli

utenti LOCALI residenti nel sistema. È presente nella stragrande maggioranza dei sistemi Unix-like e UNIX. In Mac OS X, il suo ruolo è sostituito da /Users.

usr GNU/Linux Contiene tutti i file/utility necessarie all'utente/i in modalità multiuser

var GNU/Linux Contiene file soggetti a variazioni (es. logs) sbin GNU/Linux Utility di sistema che richiedono privilegi media

GNU/Linux Volumi esterni mnt

Si consiglia la consultazione della seguente pagina di manuale relativa alla descrizione della gerarchia del file system: http://www.kernel.org/doc/man-pages/online/pages/man7/hier.7.html

Comando Descrizione

ssh [email protected] Connetti ad una sessione SSH (Secure Shell) clear Pulisci la schermata del terminale who Restituisce a video tutti gli utenti connessi attualmente

alla macchina whoami Restituisce il nome utente dell’utente attualmente

connesso al sistema exit Disconnessione

Page 4: Appunti del corso di Sistemi Operativi

4

Combinazione da tastiera Comando UNIX

CTRL+C Chiudi la linea di comando (End-Of-Text Character) CTRL+D Termina (End-Of-Transmission Character) CTRL+A Torna ad inizio riga CTRL+E Vai a fine riga TAB Autocompletamento

⌘S Salva

⌥ F5 Tilde ~ (Option+F5)

⌥ ⌘⎋ Uscita forzata Option (Alt) + Command (Mela) + Esc

Scorciatoie da tastiera MacOS X:

http://support.apple.com/kb/ht1343?viewlocale=it_it&locale=it_it Comandi comuni Unix:

http://www.ensyncsolutions.com/library/unix_commands.pdf

Tabella delle ridirezioni:

Page 5: Appunti del corso di Sistemi Operativi

5

Comando Descrizione

mkdir nomecartella Crea una cartella di nome “nomecartella” rmdir nomecartella Elimina la cartella di nome “nomecartella” touch nomefile Crea un file vuoto di nome “nomefile” rm nomefile Elimina il file di nome “nomefile” mv1 file1 file2 Rinomina/Sposta il file sorgente nel file di destinazione, se

il file di destinazione esiste, sarà sovrascritto. ls nomefile Informazioni sul file ls -la nomefile Informazioni dettagliate sul file indicato ls -la ../nomefile Verifica l’esistenza2 del file “nomefile” nella cartella parent3

e fornise informazioni dettagliate su di esso. pwd Visualizza la cartella di lavoro corrente mv nomefile ../nomefile Sposta il file “nomefile” nella cartella parent mv ../nomefile . Sposta il file “nomefile” dalla cartella parent alla cartella

attuale cp file1 file2 Copia “file1” in “file2” 4 history Visualizza l’elenco dei comandi utilizzati (storico) !155 Esegui il comando n°155 dalla cronologia dei comandi

utilizzati. echo testo Ripete ciò che è scritto dopo, ad esempio “testo”

Attenzione!

Per inserire uno spazio nel nome di un file è necessario inserire un simbolo di backslash “\” prima

dello spazio: es. nome\ del\ file

1 Comando “Move” - http://man.cx/mv 2 Esiste un comando specifico per verificare l’esistenza di un file: test(1). Es: [ -e ../file ] - http://man.cx/test 3 Parent: cartella di livello superiore alla cartella corrente. 4 Fare riferimento alla relativa pagina di manuale - http://man.cx/cp

Page 6: Appunti del corso di Sistemi Operativi

6

Permessi Ogni file ha un set di privilegi/permessi e sono elencati nelle prime 10 colonne dell’output del

comando ls -la

d r w x r - x r - x Tipo File

Lettura Scrittura Esecuzione Lettura Scrittura Esecuzione Lettura Scrittura Esecuzione

Permessi Owner Permessi Gruppo Permessi Utente

Mnemonicamente è utile l’acronimo UGO (User - Group - Others)

Nella prima colonna si possono trovare i seguenti valori:

Valore Descrizione

d Directory (Cartella) - File regolare

Le altre colonne possono riportare i seguenti valori:

Valore Descrizione

r Lettura w Scrittura x Esecuzione - Nessun permesso

Permessi in formato Ottale I permessi possono essere espressi anche in formato ottale, segue uno schema:

Valore Ottale Descrizione

r 4 Lettura w 2 Scrittura x 1 Esecuzione

In questo sistema, la combinazione di permessi r+w+x è uguale a 4+2+1 = 7, di conseguenza il 7

corrisponde ai massimi privilegi sul file. Utilizzando il sistema ottale, i 9 valori relativi ai privilegi sul

file, si riducono a soli 3 valori:

7 7 7 Owner Gruppo Utente

I tre valori utilizzati nel sistema ottale possono essere sommati tra di loro e di conseguenza generare

differenti combinazioni corrispondenti ad una determinata tipologia di permessi:

Il valore 3, corrisponde alla combinazione wx, cioè il risultato della somma di "1+2", in questo

modo si assegnano i permessi di esecuzione e scrittura.

La cifra 5, corrisponde alla combinazione rx, cioè il risultato della somma di "1+4", in questo

modo si assegnano i permessi di esecuzione e lettura.

La cifra 6, corrisponde alla combinazione rw, cioè il risultato della somma di "2+4", in questo

modo si assegnano i permessi di scrittura e lettura.

La cifra 7, corrisponde alla combinazione rwx, cioè il risultato della somma di "1+2+4", in

questo modo si assegnano i permessi di esecuzione, scrittura e lettura.

Page 7: Appunti del corso di Sistemi Operativi

7

Assegnare/Modificare i privilegi di un file

Comando Descrizione

chmod5 permessi nomefile Assegna i permessi al file o alla directory indicata chmod g+w nomefile Assegna i permessi di scrittura al gruppo per il file indicato chmod g-rw nomefile Elimina i permessi di scrittura e lettura al gruppo per il file chmod 770 nomefile Assegna i permessi completi al file per owner e gruppo,

nessun permesso agli altri. chown6 newowner file Cambia il proprietario del file in “newowner” chgrp7 newgroup file Cambia il gruppo per il file in “newgroup”

Comando Descrizione

edit nomefile Apri il file “nomefile” in modalità modifica con TextWrangler (MacOS) nano nomefile Modifica il file “nomefile” da terminale con l’editor Nano (GNU/Linux) which nomecomando Visualizza a schermo il file (ed il path) che eseguo quando utilizziamo

il comando “nomecomando”

Utilizzo del manuale

Comando Descrizione

man nomecomando Apre la pagina di manuale relativa al comando “nomecomando” man cp Apre la pagina di manuale relativa al comando “cp” BARRA SPAZIATRICE Avanza di una schermata nel manuale B Torna indietro Q Chiudi il manuale e ritorna al terminale /read Cerca “read” nel manuale

Comando Descrizione

wc nomefile Conta le righe, le parole ed i caratteri presenti nel file “nomefile” 8 wc stdin9 + CTRL+D Accetta input dallo stdin fino al comando CTRL+D cat nomefile Visualizza nel terminale il contenuto del file “nomefile” cat stdin + CTRL+D Accetta input dallo stdin fino al comando CTRL+D > Ridirigi lo stdout10 < Ridirigi lo stdin | Il carattere pipe (tubo) mette in comunicazione lo stdout di un

comando allo stdin di un altro comando. Alcuni esempi di utilizzo di comandi concatenati con il pipe

Comando Descrizione

ls -la | wc Manda in input al comando “wc” l’output del comando “ls -la” rev Rovescia ogni riga che gli viene fornita come input

5 Comando chmod: Change the File Mode - http://man.cx/chmod 6 Comando chown: Change the File Ownership - http://man.cx/chown 7 Comando chgrp: Change the File Group Ownership - http://man.cx/chgrp 8 Comando wc: Word, Line and Byte or Character Counter - http://man.cx/wc 9 Stdin: Standard Input, in generale la tastiera 10 Stdout: Standard Output, in generale il terminale, lo schermo

Page 8: Appunti del corso di Sistemi Operativi

8

ls -la | rev Prende in input e rovescia l’output del comando “ls -la” ls -la | rev | edit Prende in input e rovescia l’output del comando “ls -la” ed apre

TextWrangler con quell’input. ls -la | rev | sort Prende in input e rovescia l’output del comando “ls -la” ed ordina

l’output comando >>11 nomefile Aggiungi l’output di un comando ad un file “nomefile” già esistente history >> nomefile Salva la cronologia dei comandi in un file dal nome “nomefile” uniq Elimina dal file di input righe adiacenti uguali12 cut13 Taglia i campi selezionati da ogni riga dell’input ls -la | cut -c1-10 Taglia dall’input le prime 10 colonne ls -la | cut -c1-5, 10-15 Taglia dall’input le prime 5 colonne e le colonne dalla 10 alla 15 grep pattern file Filtra una stringa pattern all’interno di un file cat nomefile.txt | grep wc Cerca “wc” nel file “nomefile.txt”

Script È possibile creare degli script personalizzati che eseguano un set di comandi quando sono lanciati. Ogni script inizia con la cosiddetta riga dello “Shebang”14 che indica al terminale di eseguire lo script con bash15. La riga dello shebang si compone come segue: #!/bin/bash

Cioè dai caratteri #! e dal percorso dell’interprete (in questo caso “bash”) che deve eseguire lo script. Il carattere # posto all’inizio di una riga dello script indica che tale riga costituisce un commento, pertanto essa non viene eseguita dall’interprete. Prima di eseguire uno script, è necessario renderlo eseguibile assegnando i privilegi di esecuzione con l’apposito comando chmod: chmod 700 nomescript # assegno i permessi di esecuzione esclusivamente all’owner del file

Per eseguire lo script, supponendo che si trovi nella cartella di corrente16 scriviamo nel terminale il seguente comando: ./nomescript

$PATH è una variabile d’ambiente tipica dei sistemi operativi Unix che specifica un insieme di directory che contengono i programmi eseguibili. Generalmente tali percorsi sono: /bin /usr/bin /usr/local/bin

Per visualizzare il valore della variabile sul sistema in uso, digitare: echo $PATH

11 Append ( >> ): aggiunge contenuto ad un file esistente 12 Si consiglia di lavorare su file già ordinati mediante il comando sort 13 Comando Cut - http://man.cx/cut 14 Shebang: http://en.wikipedia.org/wiki/Shebang_(Unix) 15 Bourne Again Shell: shell testuale del progetto GNU usata nei sistemi operativi Unix e Unix-like 16 Per verificare la cartella di lavoro corrente (Current Working Directory) utilizzare il comando pwd

Page 9: Appunti del corso di Sistemi Operativi

9

L’insieme delle variabili predefinite nella macchina in uso è visibile utilizzando il comando seguente: env17

Comando Descrizione

a=34 Dichiara una variabile a18 assegnandole il valore 34 echo $a Visualizza il valore della variabile a echo $((4*67)) Stampa una stringa contenente l’output di un comando echo !! Sostituisce l’ultimo comando c=$((4*67)) Assegna il risultato dell’operazione alla variabile c c=‘$(4*67)’ Assegna la stringa alla variabile c

Per copiare un file da una macchina all’altra, eseguire il comando scp19: scp nomefile [email protected]:cartella

Il comando scp utilizza ssh per copiare il file dal computer in uso ad un altro computer remoto. Per creare un file contenente informazioni sugli utenti connessi al computer eseguire il seguente comando: echo who | cut -f1 -d' ' | sort | uniq | wc -l >> risultati

La sintassi precedente eseguirà il comando who e ne filtrerà l’output, eliminando il primo campo (-f1) utilizzando come separatore lo spazio vuoto (-d‘ ’), eseguirà l’ordinamento (sort), eliminerà le righe duplicate (uniq), eseguirà il conteggio delle righe (wc -l) e scriverà il tutto nel file “risultati” (>> risultati) . Quello analizzato sopra è un classico esempio di concatenazione di comandi eseguiti grazie al carattere di pipe |.

Processi Un processo è un programma in esecuzione. Un sistema multitasking 20 esegue contemporaneamente più processi. Ad ogni processo è assegnato un quantitativo di tempo di esecuzione, la slice21 tipica è pari a 10ms. Nei sistemi operativi Unix e Unix-like PID è l'acronimo di process identifier (identificativo di processo)

ed è un numero intero non negativo assegnato automaticamente che identifica in maniera univoca un

processo all'interno del sistema e rimane costante per tutta la durata di generazione ed esecuzione del

processo cioè fino alla sua terminazione.

Il PID è un attributo del process control block.

17 Il comando env sta per “environment” - http://man.cx/env 18 Le variabili definite nella shell non sono visibili dagli script (Scope delle variabili) 19 Comando scp: secure copy - http://man.cx/scp 20 Multitasking: http://it.wikipedia.org/wiki/Multitasking e Time-Sharing: http://it.wikipedia.org/wiki/Time-sharing 21Multitasking - http://en.wikipedia.org/wiki/Preemption_(computing)

Page 10: Appunti del corso di Sistemi Operativi

10

Dal terminale è possibile avviare un “task manager”, che fornisce una vista interattiva dei processi, aggiornata ogni secondo, utlizzando il seguente comando: top

Ulteriori comandi consentono la gestione dei processi e la visualizzazione di numerose informazioni sui processi in esecuzione. Comando Descrizione

top Vista processi, aggiornata ogni secondo q Uscita dal comando “top” ps “Process Show”, visualizzazione statica dei processi22 tty Visualizza il terminale attualmente utilizzato23 ps -ef Visualizza i processi applicando una specifica formattazione

Colonne UID (User ID) e PID (Process ID) ps -ef | wc -l Conta le righe stampate dal comando precedente ps -ef | less Applica la paginazione per l’output del comando precedente:

b per pagina precedente, n per successiva, / per cercare. ps -p $$ Visualizza il PID del bash id Visualizza l’ID dell’utente corrente sulla macchina id root Visualizza l’ID utente della root less /etc/passwd Visualizza le informazioni sugli account utente24 applicando la

paginazione grep nome /etc/passwd Cerca informazioni sull’account “nome” nel file degli account utente ls -la $(which ps) Stampa i dettagli relativi al file del comando “ps” ls -la $(which ssh) Stampa i dettagli relativi al file del comando “ssh” uname Visualizza il nome del sistema su cui stiamo lavorando25 uname -a Ulteriori dettagli sul sistema in uso26

Comandi condizionali

Comando Descrizione

echo $? Restituisce 0 se il comando ha funzionato, 1 se ha fallito. Si basa sugli Exit Status dei vari comandi

date ; who Lista di comandi, può essere composta anche da un solo comando if date; echo ciao; fi Lista di comandi separati dal simbolo di semicolonna “;” test -f nomefile Verifica l’esistenza del file “nomefile” 27 test 11 -gt 9 echo $?

Valuta l’espressione, verificando se il primo numero è algebricamente maggiore del secondo numero. La seconda riga, restituisce 0 se l’espressione è vera, 1 se l’espressione è falsa. In questo caso 0

test 11 \> 9 echo $?

Valuta l’espressione, verificando se il primo numero è maggiore del secondo numero. La seconda riga, restituisce 0 se l’espressione è vera, 1 se l’espressione è falsa. In questo caso 1.

which [ Vedi il percorso del comando [ . Il comando [ sostituisce test [ 11 \> 9 ] È equivalente all’utilizzo del comando test

22 Process Show mostra esclusivamente i processi dell’utente che sono legati ad un terminale - http://man.cx/ps 23 Nei sistemi Unix-like, anche i terminali sono visti come se fossero file 24 File contenente informazioni sugli account utente - http://en.wikipedia.org/wiki/Passwd_(file) 25 Su MacOS X restituirà Darwin, il nome del kernel - http://en.wikipedia.org/wiki/Darwin_(operating_system) 26 Comando uname: http://man.cx/uname 27 Il comando test valuta un’espressione - http://man.cx/test

Page 11: Appunti del corso di Sistemi Operativi

11

È possibile costruire delle liste di comande anche utilizzando il comando “[”: if [ 11 \> 9 ]; then date; fi

Nel comando precedente, così come nella tabella precedente, il simbolo di “maggiore” (>) è stato preceduto dal simbolo di backslash (\); ciò per impedire alla shell di considerare il simbolo > come carattere di redirect dell’output.

Alcuni script e la portabilità MacOS X / Linux Il comando stat28 visualizza lo stato del file system oppure di un singolo file. Il seguente script, chiamato bistat, consentirà l’esecuzione del comando stat sia su macchine equipaggiate con MacOS X sia su sistemi GNU/Linux. #!/bin/bash # bistat if[ $(uname) == Darwin ]; then stat -x $1; else stat $1; fi

Quando si utilizzano le variabili, è necessario far precedere il nome dal simbolo $. Una versione alternativa dello script bistat potrebbe essere la seguente: #!/bin/bash # bistat stringa=$(uname) if[ stringa == Linux ] then stat $1 else -x $1 fi

O ancora: #!/bin/bash # bistat stringa=$(uname) comando1="stat $1" comando2="stat -x $1" if[ stringa == Linux } then $comando1 else $comando2

Tipi di parentesi:

( ) Brackets (Round Brackets)

[ ] Square Brackets

{ } Brace Brackets

28 Comando stat - http://man.cx/stat

Page 12: Appunti del corso di Sistemi Operativi

12

Quoting Esistono due tipi di quoting29 e tre simboli che consentono di attivarne le funzionalità:

STRONG QUOTING WEAK QUOTING

Annulla il metavalore di qualsiasi carattere Salva il metavalore di alcuni caratteri rispetto allo

strong quoting.

Simboli di quoting

‘’ Strong Quoting “” Weak Quoting

\ Backslash

Wildcards

Esistono alcuni caratteri “Jolly” che la shell interpreta in modo particolare. Wildcard Descrizione

* Sostituisce uno o più caratteri (compreso il carattere nullo) all’interno del nome di un file o della sua estensione.

? Sostituisce un solo carattere all’interno del nome di un file o della sua estensione.

[ ] Le parentesi quadre racchiudono un elenco di caratteri, ognuno dei quali può sostituire un singolo carattere in una posizione.

- Un trattino (hyphen) usato all’interno delle [ ] denota un range di caratteri da sostituire, es. [a-z] oppure [0-9]

~ Il simbolo di tilde, ad inizio parola, espande il nome della home directory dell’utente attuale. Se il simbolo tilde è seguito dal nome di un altro utente, farà riferimento alla home directory dell’utente indicato.

Espansioni della shell La shell espande in un particolare ordine dopo la divisione in parole (token separati da spazi o

tabulatori).

Tipi di espansione30:

Brace Expansion

Tilde Expansion

Parameter Expansion

Command Substitution

Arithmetic Expansion

Process Substitution

Word Splitting

Pathname Expansion ( *, ? )

Brace Expansion

echo a{b,c,d}e

29 http://wiki.bash-hackers.org/syntax/quoting#weak_quoting 30 Shell Command Language - http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html

Page 13: Appunti del corso di Sistemi Operativi

13

Il comando restituirà le seguenti combinazioni: abe, ace, ade. Allo stesso modo, grazie alla brace expansion della shell si possono ottenere tutte le combinazioni tra queste due coppie di opzioni, eseguendo il comando: echo {1,X,2},{1,X,2}

E ancora, è possibile cancellare tutti i file dal nome composto dalla parola “file” seguita da una combinazione di 0, 1 e 2. (es. file001, file000, file002, file012, ecc.) rm file[0-2][0-2][02]

File e directory

In Unix, a differenza di quanto avviene in altri sistemi operativi, tutti i file vengono tenuti all’interno

di un unico albero la cui radice (quella che viene chiamata root directory) viene montata

all’avvio. Un file viene identificato dall’utente usando quello che viene chiamato pathname, cioè

il percorso che si deve fare per accedere al file a partire dalla root directory, che è composto da

una serie di nomi separati da una “/”.

Una directory è anch’essa un file, solo che è un file particolare che il kernel riconosce come tale. Il suo

scopo è quello di contenere una lista di nomi di file e le informazioni che associano ciascun nome al

contenuto. Dato che questi nomi possono corrispondere ad un qualunque oggetto del filesystem,

compresa un’altra directory, si ottiene naturalmente un’organizzazione ad albero inserendo nomi di

directory in altre directory.

Il nome completo di un file viene chiamato pathname ed il procedimento con cui si individua il file a

cui esso fa riferimento è chiamato risoluzione del nome (filename resolution o pathname resolution).

Una delle differenze principali con altri sistemi operativi è che per unix tutti i file di dati sono identici e

contengono un flusso continuo di byte.

Un’altra differenza è nel formato dei file di testo: in Unix la fine riga è codificata in modo diverso da

Windows, in particolare il fine riga è il carattere LF (o \n) al posto del CR (\r) del vecchio MacOS e del

CR LF di Windows.

Il filesystem Unix

Lo spazio fisico di un disco viene usualmente diviso in partizioni; ogni partizione può contenere un filesystem. La strutturazione tipica dell’informazione su un disco che utilizza il filesystem ext2 prevede una separazione dei dati in block group che replicano il superblock31. È comunque caratteristica comune di tutti i filesystem per Unix, prevedere una divisione fra la lista degli inode e lo spazio a disposizione per i dati e le directory.32 È importante tenere presente che:

1. L’inode contiene tutte le informazioni (metadati) riguardanti il file: tipo di file, permessi di accesso, dimensioni, puntatori ai blocchi fisici che contengono i dati. Il comando stat fornisce informazioni che provengono dall’inode. Dentro una directory si troverà esclusivamente il nome del file ed il numero dell’inode ad esso associato.

2. Si possono avere più voci che puntano allo stesso inode. Ogni inode ha un contatore che contiene il numero di riferimenti che sono stati fatti ad esso (link count); solo quando questo contatore si annulla i dati del file vengono rimossi dal disco. Tale funzione è detta unlink e in realtà non cancella i dati del file, ma si limita ad eliminare la relativa voce da una directory e decrementare il numero di riferimenti nell’inode.

31 Ogni filesystem contiene un superblock che contiene informazioni sul filesystem: tipo di filesystem, dimensione, stato, informazioni sulle altre strutture di metadati. 32 GaPiL - pg. 103-105 - http://gapil.gnulinux.it/files/2011/12/gapil.pdf

Page 14: Appunti del corso di Sistemi Operativi

14

3. Il numero di inode si riferisce sempre ad un inode nello stesso filesystem, non è possibile che una directory contenga riferimenti ad inode relativi ad altri filesystem.

4. Quando si cambia nome ad un file senza cambiare filesystem, il contenuto del file non viene spostato fisicamente, ma viene semplicemente creata una nuova voce per l’inode in questione e rimossa la vecchia.

5. Gli inode dei file, che contengono i metadati ed i blocchi di spazio disco, che contengono i dati, sono risorse indipendenti ed in genere vengono gestite come tali anche dai diversi filesystem; è pertanto possibile sia esaurire lo spazio disco che lo spazio per gli inode, nel primo caso non sarà possibile allocare ulteriore spazio, ma si potranno creare file vuoti, nel secondo non si potranno creare nuovi file, ma si potranno estendere quelli che ci sono.

I file non hanno nome negli inode. La numerazioni degli inode è unica in ogni filesystem.

Data Descrizione

ACCESS Ultima data di accesso al file MODIFY Data in cui vi è stata una modifica al contenuto del file CHANGE Data in cui vi è stata una modifica ai metadati del file Comando Descrizione

ls -li Mostra il numero di inode di ogni file stat -x nomefile Mostra informazioni sul file contenuti nell’inode.33 apropos contents Esegui una ricerca nel manuale di sistema per la parola “contents”34

Iterazioni e cicli

Ciclo infinito

Se eseguiamo il comando seguente, provocheremo un ciclo infinito, poiché il comando true35 non sarà

mai falso. Il comando che usa l’istruzione di iterazione while, dopo aver verificato la condizione

d’iterazione, eseguirà il comando date che manderà in output la data corrente, attenderà per una

pausa di un secondo e ripeterà il ciclo, valutando nuovamente la condizione d’iterazione.

while true; do date; sleep 1; done

Per interrompere il comando, premere la combinazione di tasti CTRL+D dalla tastiera.

Altri cicli

for aaa in 1 3 67 890 > do > echo $(($aaa * 2) > done

for ((a=1;a<15:a++)); do echo $a; done

33 Il nome del file non è contenuto nell’inode 34 Comando apropos - http://man.cx/apropos 35 Comando true - http://man.cx/true

Page 15: Appunti del corso di Sistemi Operativi

15

Calcolatore

Comando Descrizione

bc Calcolatore36 scale=4 Restituirà il risultato approssimato a 4 cifre decimali scale=40 Restituirà il risultato approssimato a 40 cifre decimali 7/3 Restituirà “2,3333”37

Stdin, Stdout, Stderr Lo standard error (stderr) e lo standard output (stdout) per default sono inviati al terminale.

Ad ognuno di questi stream38 standard corrisponde un numero, grazie al quale è possibile

reindirizzarne il canale predefinito, ad esempio per scrivere all’interno di un file.

Codice Stream

0 Stdin - Standard Input (default: Tastiera) 1 Stdout - Standard Output (default: Terminale) 2 Stderr - Standard Error (default: Terminale) Ad esempio: ls * 1> nomefile

Ridirige l’output del comando ls * in un file denominato “nomefile”.

ls nome_file_non_esistente 2> errore

Eseguendo il comando ls su un file che non esiste e reindirizzando lo standard error in un file

denominato “errore”, troveremo un messaggio di errore simile al seguente:

Such file does not exist

Altri comandi

Comando Descrizione

tty Vedi il terminale utilizzato al momento cat > /dev/ttys000 Ridirige l’input su un altro terminale /dev/null File speciale che elimina tutto ciò che riceve39 cat /dev/random40 > nomefile Scrive bit a caso in un file (per bloccare CTRL+D) head nomefile Vedi le prime 10 righe del file “nomefile”41 head -30 nomefile Vedi le prime 30 righe del file “nomefile” head -3 nomefile Vedi le prime 3 righe del file “nomefile” tail nomefile Vedi le ultime 10 righe del file “nomefile”42

36 Utilità calcolatore - http://man.cx/bc 37 Se prima si applicherà il comando scale=4 38 Panoramica sugli Standard stream - http://en.wikipedia.org/wiki/Standard_streams 39 The Null Device - http://en.wikipedia.org/wiki//dev/null 40 Random Number Generator - http://en.wikipedia.org/wiki//dev/random 41 Comando Head - http://man.cx/head

Page 16: Appunti del corso di Sistemi Operativi

16

Il comando mostra la riga 25 del file indicato:

head -25 nomefile.txt | tail -1

Il seguente comando mostra la riga 25 del file indicato e visualizza anche il numero di riga:

cat -n nomefile.txt | head -25 | tail -1

Il seguente file contiene tutte le parole della lingua inglese, per aprirlo con TextWrangler scrivere:

edit usr/share/dict/words

Comando Descrizione

system_profiler Visualizza le informazioni di sistema (MacOS X)43 basename nomedirectory Restituisce il nome della directory44 basename $(pwd) Restituisce il nome della directory attuale stat -f%i nomedirectory Restituisce l’inode della directory “nomedirectory” (MacOS X) stat -c%i * Restituisce gli inode di tutti i file di quella directory (GNU/Linux) stat -c%Y * Vedi le date45 di tutti i file della directory corrente OPTION+F5 ~ (Tilde)

Cercare file Il comando find46 consente di cercare file all’interno di una directory, sulla base di un criterio, segue

la sintassi generica del comando.

find directory criterio

Ad esempio il seguente comando cerca all’interno della cartella home dell’utente (~), utilizzando la ricerca per nome, il file di nome “nomefile”. find ~ -name nomefile

Mentre il seguente comando restituisce tutti i file e le cartelle che si chiamano dir*: find ~ -name dir\*47

Il seguente comando stampa a video i risultati della ricerca (anche se find lo fa di default)

find ~ -name dir\* -print

42 Comando Tail - http://en.wikipedia.org/wiki/Tail_(Unix) 43 Comando system_profiler - https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man8/system_profiler.8.html 44 Comando basename - http://man.cx/basename 45 Le date sono espresse in secondi a partire dal 01/01/1970 (Epoch) 46 Comando find - http://man.cx/find 47 Il carattere * è stato preceduto da uno backslash \ per evitare la pathname expansion della shell

Page 17: Appunti del corso di Sistemi Operativi

17

Il seguente comando filtra i risultati per tipo di file # cerca solo i file find ~ -name dir\* -type f # cerca solo le cartelle find ~ -name dir\* -type d

È possibile combinare le ricerche, imponendo una condizione OR tra i tipi: find ~ -name dir\* \(-type f -o -type d\) -print

Nell’esempio seguente, il comando cercherà i file di 102 byte. find ~ -size 102c

Altri esempi:

find ~ -name dir\* -type f -exec file {} \; find ~ -size -100c -exec stat -c%s \; 2> /dev/null find ~ -size -100c -size +50c -exec stat -f%z {} ; 2> /dev/null

Script Costruire uno script che prenda come argomento il nome di una directory e faccia la somma delle

dimensioni in byte dei file in essa contenuti.

#!/bin/bash if[ $(uname) == Darwin ] then find $* -type f -exec stat -f%z {} \; 2>/dev/null | tr \\n + echo 0 elif[ $(uname) == Linux ] find $* -type f -exec stat -c%s {} \; 2>/dev/null | tr \\n + echo 0 then echo Che sistema operativo utilizzi? fi | bc echo '$* = ' $*

Il comando principale del nostro script sarà: find $* -type f -exec stat -f%z {} \;

Che si occuperà (in ambiente MacOS X) di trovare tutti i file nella cartella.

Il comando tr48 si occuperà della trasformazione gli ‘a capo’ (newline) in un +.

tr \\n +

48 Translate Characters - http://man.cx/tr

Page 18: Appunti del corso di Sistemi Operativi

18

Oppure nell’esempio seguente, trasformiamo tutti i caratteri di ‘:’ in uno spazio bianco:

echo $PATH | tr :\ ' '

Utilizzo del comando grep

Cercare la stringa “inu” all’interno di un file denominato “sommabytes.sh”

grep inu sommabytes.sh

Cercare la stringa “inu” all’interno del file del dizionario: grep inu /usr/share/dict/words

Cercare la stringa “inu” in tutti I file della directory corrente: grep -r inu .

Copiare un file da un computer remoto al pc locale, ad esempio il file del dizionario italiano scp [email protected]:/usr/share/dict/italian .

grep [abc]...[xyz] italian

Simbolo Descrizione

^ Caret - Inizio riga (All’interno delle Square Brackets assume un significato diverso)

$ A fine stringa, indica la fine della parola

grep '^[abc]...[xyz]' italian

grep '^[abc]...[xyz]$' italian

Cercare nel file indicato le parole che iniziano per “r” e che terminano per “sa” e che abbiano 3 caratteri tra inizio e fine parola: grep '^r...sa$' /Users/Name/Desktop/italian

Cercare nel file indicato tutte le parole che contengono almeno tre vocali di seguito: grep -E '[^aeiou]{3,}' italian

Cercare le parole che contengono almeno 5 vocali di seguito: grep -E '[^aeiou]{5,}' italian

Per le parole che contengono solo 5 vocali di seguito: grep -E '[^aeiou]{5}' italian

Page 19: Appunti del corso di Sistemi Operativi

19

Parameter Expansion49

Definire una variabile “a” e visualizzare il suo valore a terminale:

a=10 echo $a

Concatenare al valore di “a” un numero:

echo ${a}4

Se il “parameter” è non impostato o nullo, l’espansione di “word” è sostituita. Altrimenti è “parameter” manterrà il suo valore: ${parameter:-word}

Se il “parameter” è non impostato o nullo, assegna a “parameter” il valore di “word”: ${parameter:=word}

Se il “parameter” non è impostato o è nullo, l’espansione di “word” (oppure un messaggio che informa della non esistenza di “word”) è scritto nello standard error e la shell, se non interattiva, termina. Altrimenti viene mantenuto il valore di “parameter”: ${parameter:?word}

Se il “parameter” non è impostato o è nullo, non verrà modificato, altrimenti, sostituirà il valore del parametro con l’espansione di “word”: ${parameter:+word}

Definisci un offset: ${parameter:offset} ${parameter:offset:lunghezza}

Ad esempio: a=ABCDEFGHIL echo $a echo ${a:4} echo ${a:4:3}

Visualizzerà: ABCDEFGHIL Visualizzerà: EFGHIL Visualizzerà: EFG

Il comando seguente restituisce la lunghezza della stringa assegnata ad una variabile: echo ${#a}

49 Bash Expansions - http://man.cx/bash#heading14

Page 20: Appunti del corso di Sistemi Operativi

20

Trova la stringa “CDE” e la sostituisce con “123”. Attenzione! Il valore di “a” non cambia. Sarà sostituita solo la prima occorrenza:

echo ${a/CDE/123}

Per effettuare la sostituzione in tutte le occorrenze: echo ${a//CDE/123}

Per eliminare il match più corto del “pattern”: ${parameter#pattern}

Per eliminare il match più lungo: ${parameter##pattern}

Date ed orari

I comandi presentati di seguito mostrano una serie di utilizzi e di formattazione della data.

Comando Descrizione/Risultato

date Thu Apr 12 16:10:00 CEST 2012 - Data completa date +%A Mostra il nome completo del giorno della settimana: es. Thursday date +%h Mostra il mese date +%H Mostra l’ora date +%H%M%S Visualizza ore, minuti e secondi, senza separatori: es. 085012 date +%H:%M:%S Visualizza ore, minuti e secondi con separatori: es. 08:50:12 date "+%H:%M:%S $a" Visualizza l’orario completo ed il valore della variabile “a” date +%Y Visualizza l’anno date +%Y%m%d%H%M%S 20120412162016 - visualizza data ed ora complete, senza separatori cal Visualizza il calendario del mese corrente cal anno Visualizza il calendario dell’anno indicato cal 2012 Visualizza il calendario dell’anno 2012 Per visualizzare la data attuale completa, formattata, eseguire: date "+%d/%m/%Y %H:%M:%S"

che restituirà un output simile al seguente: 12/04/2012 16:21:16

Page 21: Appunti del corso di Sistemi Operativi

21

Script

Costruire uno script che prenda come argomento una directory e tolga gli spazi dai nomi dei file in essa

contenuti.

Innanzitutto creare una cartella e creare al suo interno una serie di file che contengano spazi all’interno del nome: mkdir nomecartella cd nomecartella touch file\ 001 file\ 002 file\ 003 file\ 004 file\ 005

Il comando che elimina gli spazi può essere semplificato ad una singola riga: for i in *; do mv "$i" ${i/Nome con spazio/NomeSenzaSpazio}; done

Tuttavia il comando precedente lavorerà esclusivamente con i file che abbiano come nome il pattern indicato nel comando stesso, nell’esempio “Nome con spazio”. Anche con il comando “tr50” è possibile eliminare gli spazi: touch "gita al mare"005 echo gita\ al\ mare005 | tr -d ' '

Segue lo script completo per l’eliminazione degli spazi dai nomi dei file:

“stripspaces.sh”

#!/bin/bash cd $1 for FILE in * do FILE_NEW=$(echo "$FILE" | tr -d ' ') mv $FILE_NEW done

Per sostituire gli spazi con un underscore, il comando “tr” deve essere così strutturato: tr ' ' '_'

Il medesimo script per non considerare le directory, diventerà: #!/bin/bash cd $1 for FILE in * do if [-f "$FILE" ]; then FILE_NEW=$(echo "$FILE" | tr ' ' '_') mv "$FILE" $FILE_NEW fi done

50 Comando Translate Characters - http://man.cx/tr

Page 22: Appunti del corso di Sistemi Operativi

22

Array

Assegnamento di un valore agli elementi 0, 1 e 2 del vettore “a”:

a[0]=5 a[1]=5 a[2]=6

Il comando seguente visualizzerà il vettore utilizzando un ciclo:

for i in 0 1 2 3 4 5 6; do echo elemento $i = ${a[$i]}; done

Una scrittura alternativa del comando è la seguente: for i in 0 1 2 3 4 5 6; do echo elemento $i = ${a[i]}; done

Per visualizzare la lunghezza dell’array (saranno conteggiati esclusivamente gli elementi non nulli): echo ${#a[*]}

È possibile creare e popolare un array “b” come di seguito: b=(1 34 56 78 98 34 56 23 12)

È possibile popolare un array con l’output di un comando, ad esempio: c=($(cat italian)) echo ${#c[*]}

Italian è il file del dizionario Restituirà 116878

Valori casuali

Comando Descrizione/Risultato

echo $RANDOM Genera un numero casuale echo $((15%4)) Operazione “Modulo” echo $((RANDOM*RANDOM%116878))

Genera e moltiplica fra loro due numeri casuali, successivamente esegue l’operazione modulo del numero ottenuto per 116878.

Costruire uno script che generi parole casuali dal dizionario Italiano:

“iching.sh”

#!/bin/bash c=($(cat /path/Documents/italian)) echo ${c[RANDOM]} ${c[RANDOM]} ${c[RANDOM]} ${c[RANDOM]} ${c[RANDOM]} \ ${c[RANDOM]} ${c[RANDOM]}

Page 23: Appunti del corso di Sistemi Operativi

23

Costruire uno script che estragga casualmente 7 parole dal dizionario inglese, le visualizzi a terminale

e le legga.

“iching2.sh”

#!/bin/bash c=($(cat /usr/share/dict/words)) LUNGH=${#c[*]} a="${c[$((RANDOM*RANDOM%LUNGH))]} \ ${c[$((RANDOM*RANDOM%LUNGH))]} ${c[$((RANDOM*RANDOM%LUNGH))]} ${c[$((RANDOM*RANDOM%LUNGH))]} ${c[$((RANDOM*RANDOM%LUNGH))]} ${c[$((RANDOM*RANDOM%LUNGH))]} ${c[$((RANDOM*RANDOM%LUNGH))]}" echo $a say $a

Ulteriori informazioni sui processi

Comando Descrizione

ps Visualizza i processi che utilizzano terminali tty Visualizza il terminale attualmente utilizzato id Visualizza l’ID dell’utente corrente sulla macchina id root Visualizza l’ID utente di root ps -e Visualizza tutti i processi (anche senza terminali) anche di altri utenti ps -f Vedi l’User ID (UID) ps -ef Visualizza i processi applicando una specifica formattazione

Colonne UID (User ID) e PID (Process ID) pstree (Linux) visualizza l’albero dei processi echo $$ Visualizza il Process ID del bash in esecuzione

Con il comando ps -ef i dati verranno formattati in tre colonne:

UID PID PPID

User ID Process ID Parent

Process ID

Ad ogni file sono assegnati 12 permessi totali, infatti oltre ai classici 9 bit dei permessi del proprietario, del gruppo e degli altri (U.G.O), esistono 3 bit precedenti che consentono di eseguire il processo come se si stesse utilizzando un altro account. I 3 bit in questione sono i seguenti: Bit Descrizione

4 Set User ID bit 2 Set Group ID bit 1 Sticky bit Se il bit Set User ID è impostato, quando esegue un file/processo, esso viene eseguito con l’identità del proprietario del file. Esiste infatti una differenza tra:

Real User ID Effective User ID

ID dell’utente che ha avviato il file eseguibile del processo

ID del proprietario del file che viene eseguito.

Page 24: Appunti del corso di Sistemi Operativi

24

Se ad esempio si avvia il comando di cambio password, il file associato al processo è di proprietà della root, pertanto l’Effective User ID sarà quindi “root”. /usr/bin/passwd

È possibile personalizzare l’output del comando “Process Show” ps51 specificando i campi desiderati, come negli esempi seguenti: Comando Descrizione

ps -e -opid,comm Visualizza le colonne Process ID (PID) e il comando lanciato ps -e -opid=XYZ,comm=KLM Visualizza le colonne PID e CMD personalizzandone le

intestazioni ps -e -opid=,comm= Visualizza le colonne PID e CMD con le intestazioni vuote ps -e -opid,ruid,uid,comm Visualizza le colonne PID, Real User ID, Effective User ID e CMD -time Visualizza la colonna relativa al tempo cumulativo di esecuzione

del processo ps -p XXXXX -ouid Visualizza l’UID del processo numero XXXXX

L’opzione -o del comando ps consente di specificare il formato di output sotto il controllo dell’utente:

Comando Descrizione

ps -e -opid,ruid,uid oppure

ps -e -opid,ruser,user

Visualizza le colonne Process ID (PID), la colonna Real User ID e la colonna Effective User ID (UID) di tutti i processi in esecuzione sulla macchina

ps -e -opid=ID,uid=UTENTE Visualizza PID e UID, personalizzando l’intestazione

È possibile creare un array che contenga tutti i PID dei processi attivi sul sistema: arraypid=($(ps -e -opid=)) echo ${#arraypid[*]}

Per assegnare ad “a” il valore dell’User ID che esegue un dato processo: a=$(ps -p 92174 -ouid=) echo $a

La visualizzazione dei processi può essere ulteriormente personalizzata come nell’esempio seguente: for i in $(echo ${arraypid[*]}) > do > echo processo $i eseguito da $(ps -p $i -ouid=) > done

51 Process Show - http://man.cx/ps

Page 25: Appunti del corso di Sistemi Operativi

25

Costruire uno script che inserisca in due array differenti le informazioni relative ai processi attivi nel sistema, in particolare, nel primo array inserisca il PID e nel secondo inserisca l’UID e si crei una visualizzazione a terminale che faccia corrispondere gli elementi del primo array con quelli del secondo. #!/bin/bash # ****************************** # File: psindoublearray.sh # Function: Puts in two arrays data for all the processes in the system # primoarray=($(ps -e -opid=)) for ((i=0; i < ${#primoarray[*]}; i++)) do secondoarray[i]=$(ps -p ${primoarray[i]} -ouid=) done for ((i=0; i < ${#primoarray[*]}; i++)) do echo ${primoarray[i]}-----${secondoarray[i]} done

Sostituendo nel secondo array l’UID con il Comando eseguito dal processo, si avrebbe #!/bin/bash # ****************************** # File: psindoublearray2.sh # Function: Puts in two arrays data for all the processes in the system # primoarray=($(ps -e -opid=)) for ((i=0; i < ${#primoarray[*]}; i++)) do secondoarray[i]=$(ps -p ${primoarray[i]} -comm=) done for ((i=0; i < ${#primoarray[*]}; i++)) do echo ${primoarray[i]}' <---> '${secondoarray[i]} done

Page 26: Appunti del corso di Sistemi Operativi

26

Codifica Su un computer i caratteri dell’alfabeto sono “codificati” come numeri al fine di facilitare la

memorizzazione di un testo o la sua trasmissione attraverso le reti.

Esistono una lunga serie di codifiche disponibili, le più diffuse sono: ASCII52 e Unicode53.

ASCII è un sistema di codifica dei caratteri a 7 bit, comunemente utilizzato nei calcolatori, ideato nel

1961 e divenuto standard ISO 646. Alla specifica iniziale basata su codici 7 bit, negli anni successivi,

fecero seguito una serie di estensioni ad 8 bit con lo scopo di aumentare il numero di caratteri

rappresentabili, includendo le vocali accentate e altri simboli (Extended ASCII54).

Unicode è un sistema di codifica che assegna un numero univoco ad ogni carattere usato per la

scrittura dei testi, in modo indipendente dalla lingua, dalla piattaforma e dal programma utilizzati. Il

codice assegnato al carattere viene rappresentato con U+, seguito dalle 4 (o 6) cifre esadecimale del

numero che lo individua. Unicode incorpora lo standard ISO/IEC 8859-1 e codifica i caratteri utilizzati

in quasi tutte le lingue, nonché simboli matematici, chimici, cartografici, l’alfabeto Braille, ideogrammi

e altri simboli.

UTF-855 è una codifica di caratteri Unicode in sequenze di lunghezza variabile di byte, creata da Rob

Pike e Ken Thompson. UTF-8 utilizza da 1 a 4 byte rappresentare un carattere Unicode. Un solo byte è

necessario per rappresentare i 128 caratteri dell’alfabeto ASCII (posizioni Unicode da U+0000 a

U+007F).

Comando Descrizione

hexdump file Visualizza il file indicato nel formato specificato dall’utente56 hexdump -c file Visualizza il file specificato in esadecimale, 16 caratteri per riga, in 3

colonne separate da spazi.

Una tabella dei caratteri UTF-8 può essere trovata alla pagina web: http://www.utf8-chartable.de/ I diversi sistemi operativi rappresentano in modo differente la fine di una riga di testo (newline). Il simbolo di newline57 non è un carattere visibile sullo schermo . Rappresentazione Sistema Operativo

LF Unix / Unix-like, GNU/Linux, MacOS X, FreeBSD CR MacOS (fino alla versione 9) CR+LF Microsoft Windows, DOS, Symbian OS, Palm In Unicode tali simboli sono rappresentabili:

Simbolo Descrizione Unicode

LF Line Feed U+000A CR Carriage Return U+000D CR+LF Carriage Return + Line Feed U+000D U+000A

52American Standard Code for Information Interchange - http://it.wikipedia.org/wiki/ASCII 53 Unicode - http://it.wikipedia.org/wiki/Unicode - http://www.unicode.org/ 54 Extended ASCII (ISO 8859) - http://it.wikipedia.org/wiki/ISO_8859 55 UTF-8 (Unicode Transformation Format - 8 bit) - http://it.wikipedia.org/wiki/UTF-8 56 Comando hexdump - http://man.cx/hexdump 57 Newline - http://en.wikipedia.org/wiki/Newline

Page 27: Appunti del corso di Sistemi Operativi

27

Conversioni tra codifiche È possibile modificare la codifica di un file utilizzando il comando iconv58

iconv [-f encoding] [-t encoding] [file]

Per visualizzare tutti i formati disponibili: iconv -l

Oppure per convertire il file dalla codifica ISO Latin1 alla codifica UTF-8: iconv -f L1 -t UTF-8 testo-ISOLatin1.txt

Dove L1 identifica la codifica ISO Latin1. È possibile convertire la codifica di un file e salvarne il contenuto in un nuovo file: iconv -f L1 -t UTF-8 italian_linux.txt > italian_linux_utf8.txt

È disponibile online un file di testo in formato UTF-8 che dimostra le potenzialità di questa codifica: http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-demo.txt

Job Control59 di Bash Bash consente di lanciare un job e di metterlo in background in modo tale da poter continuare ad

utilizzare il terminale per eseguire altri jobs, che quindi sono eseguiti in foreground.

Per lanciare un job e porlo in background: find / -name asdsa 2>/dev/null &

Il simbolo “&” al termine del comando, pone il job lanciato, nell’esempio “find” in background. Comando Descrizione

jobs Vedi tutti i jobs attivi CTRL+Z (^Z) Interrompe il comando fg %1 Poni in foreground il processo 1 bg Continua il job in background fg Continua il job in foreground Lo standard input è di solito indirizzato al job in foreground.

58 Iconv - codeset conversion - http://man.cx/iconv 59 Job Control - http://man.cx/bash#heading26

Page 28: Appunti del corso di Sistemi Operativi

28

Personalizzazione della shell, gli alias e le funzioni

Il file .bash_profile è uno “startup-file” di bash, esso contiene delle informazioni e delle configurazioni personalizzabili di bash. Per visualizzarne il contenuto:

cat .bash_profile

Una shell di login60 (cioè associata alla finestra) è rappresentata in “ps” (Process Show) con un trattino (hyphen) davanti al nome. Ad esempio: -bash È possibile modificare alcune opzioni della shell, modificando il file .bash_profile

Ad esempio, per personalizzare l’inizio di ogni riga del prompt61: PS1="\t -> "

È inoltre possibile definire degli alias per alcuni comandi, sempre nel file .bash_profile alias ll='ls-la'

Nell’esempio sopra, è stato creato un alias per il comando ls-la che potrà essere lanciato scrivendo

ll.

Gli alias possono essere definiti anche utilizzando le funzioni.

La funzione seguente definisce il comando pman che consente di ottenere una versione stampabile in

formato PostScript/PDF della pagina di manuale relativa al comando fornito come argomento, inoltre

apre nell’applicazione Anteprima di MacOS X, il file creato.

pman() { man -t "${1}" | open -f -a /Applications/Preview.app }

Comando Descrizione

pman bash Apre in formato PostScript il manuale di bash pman open Apre in formato PostScript il manuale di open

La funzione seguente definisce un alias per il comando ls applicato sulla home directory dell’utente. casa() { ls ~ }

In .bash_profile è possibile includere un altro file scrivendo: source .bashrc oppure . .bashrc

60 http://man.cx/bash#heading7 61 http://man.cx/bash#heading27

Page 29: Appunti del corso di Sistemi Operativi

29

Il comando seguente funziona esclusivamente per il primo file: find . -type f -name asy\* | stat -x

Mentre utilizzando xargs62 passa come argomenti tutti i file restituiti dal primo comando: find . -type f -name asy\* | xargs stat -x

Eventuali spazi nei nomi dei file possono creare problemi. Per evitare tali problemi, è possibile separare mediante un carattere NULL i risultati del comando find. find . -type f -name asy\* print0

Quindi il comando completo diventa: find . -type f -name asy\* print0 | xargs -0 stat-x

Crittografia È possibile crittografare del testo, oppure il contenuto dei file utilizzando differenti algoritmi.

Comando Descrizione

md5 Codifica restituendo un digest composto da 32 caratteri alfanumerici (solo lettere e numeri)

md5 * Restituisce il digest dei file contenuti nella directory corrente md5 -q * Mostra solo gli md5 md5 nomefile Restituisce l’hash md5 relativo al file

Su Linux il comando analogo è md5sum:

Comando Descrizione

md5sum * Restituisce il digest dei file contenuti nella directory corrente md5 * 2>/dev/null Restituisce il digest dei file contenuti nella directory corrente e

ridireziona l’output.

Il comando: echo andiamo a mangiare un gelato | md5

Restituirà l’hash md5 del contenuto del comando echo. Il comando seguente verificherà le differenze tra i file forniti come argomento: diff nomefile1 nomefile2

Esiste un ulteriore comando per la crittografia in diversi formati: openssl dgst -md5 nomefile.txt Restituisce l’hash md5 del file

openssl dgst -sha1 italian_linux.txt Restituisce l’hash sha1 del file

62 http://man.cx/xargs

Page 30: Appunti del corso di Sistemi Operativi

30

È possibile crittografare/decrittare il contenuto di un file e salvarlo in un file: openssl enc -des3 < italian_linux_utf8.txt > italian_linux_enc openssl enc -des3 -d < italian_linux_enc

L’attributo -d nell’ultimo comando indica che si tratta di una decodifica.

Scope delle variabili Una variabile definita in bash non sarà conosciuta da un bash interno ad esso.

a=5 echo $a bash echo $a

La variabile a vale 5 Aprendo un bash interno al bash principale La variabile a non sarà conosciuta

Per esportare una variabile in shell interne è necessario utilizzare il comando export a=5 echo $a export a bash echo $a

La variabile a vale 5 Esporta il valore della variabile alle altre shell Aprendo un bash interno al bash principale La variabile a vale 5

Il comando export funziona con i livelli inferiori, cioè se uso il comando export su una variabile definita in un bash di secondo livello, tale variabile sarà conosciuta dai livelli inferiori (3°, 4°, 5°, ecc.), ma non sarà conosciuta dal bash di 1° livello. Le modifiche apportare alle variabili nei livelli inferiori, non saranno applicate ai livelli superiori. echo $SHLVL Restituisce il livello di shell su cui si sta operando

Hard Link & Soft Link

Soft Link63

Si dice collegamento simbolico (o Link Simbolico / Symlink / Soft link) un particolare tipo di file che è

un rimando ad un altro file o directory. Un link simbolico è un file contenente un percorso relativo o

assoluto al file o directory a cui fa riferimento; questo permette di creare collegamenti non solo

all’interno della stessa partizione, ma anche da un file system ad un altro, offrendo più flessibilità

rispetto ad un collegamento fisico. La flessibilità si trasforma in minore affidabilità in quanto, se il file a

cui punta viene rimosso o cambiato di nome, il collegamento rimane orfano.

Per creare un link simbolico si usa il comando ln ln -s nomefile nomelink

Il soft link sarà rappresentato dal comando ls: ls -la nom* nomelink -> nomefile

63 Soft link - http://it.wikipedia.org/wiki/Collegamento_simbolico

Page 31: Appunti del corso di Sistemi Operativi

31

Hard Link64

Si dice collegamento fisico (hard link) l’associazione del nome di un file al suo contenuto. Un

collegamento fisico fa riferimento ai dati (il contenuto) di un file, e in ciò si differenzia dai collegamenti

simbolici che fanno riferimento a nomi di file. Un’altra differenza è che il collegamento fisico deve

trovarsi sullo stesso file system che contiene i dati a cui fa riferimento, e che un collegamento fisico

non può restare orfano.

Per ogni file o directory nei sistemi Unix il file system mantiene un identificativo univoco (inode) ed un

conteggio degli hard link che vi fanno riferimento. Un hard link contiene semplicemente il nome ed il

riferimento all’inode del file, senza altre informazioni.

L’eliminazione di un file (cioè di un suo collegamento fisico) non implica l’annullamento di tutti i

collegamenti fisici ad esso, perché ogni hard link è indipendente. Lo spazio occupato dai dati può

essere liberato solo quando il conteggio degli hard link di un file diventa zero.

Per creare un link simbolico si usa il comando ln ln nomefile nomelink

Le directory hanno sempre gemelli (cioè hard link che le puntano) poiché sono referenziate dalle directory figlie e dalla directory parent. Comando Descrizione

echo $SECONDS Tempo, in secondi, dall’avvio della shell echo $COLUMNS Visualizza il numero delle colonne della shell attiva COLUMNS=70 ./nomescript Imposta il numero delle colonne a 70 per eseguire lo script indicato

Operazioni matematiche bc 4/3 scale=10 4/3 scale=4 4/3 bc -l s(5) s(x) c(x) a(x) l(x) e(x) echo 4/3 | bc echo 4/3 | bc -l echo 'scale=5;4/3' | bc

Apre un ambiente matematico Restituirà 1 Utilizza un’approssimazione a 10 cifre decimali Restituirà 1,3333333333 Utilizza un’approssimazione a 4 cifre decimali Restituirà 1,3333 Carica la libreria standard delle funzioni matematiche sin(5) = -.958… rad sin(x) cos(x) arctan(x) logaritmo(x) esponenziale(x) Restituirà 1 Restituirà 1,333… approssimato a 20 cifre decimali Restituirà 1,33333

64 Hard Link - http://it.wikipedia.org/wiki/Collegamento_fisico

Page 32: Appunti del corso di Sistemi Operativi

32

Browser da riga di comando È possibile visualizzare in versione testuale siti internet e pagine web utilizzando il browser da riga di

comando Lynx65. È possibile scaricare l’ultima versione di Lynx dal sito ufficiale del progetto66.

Per visitare ad esempio, il sito www.repubblica.it, si scriverà il seguente comando nel terminale: lynx http://www.repubblica.it

Per scaricare la pagina web contenente il testo completo della Divina Commedia: lynx -dump http://www.filosofico.net/ladivinacommedia.htm

Esercizio

Trovare la parola più utilizzata nella Divina Commedia.

Innanzitutto è necessario scaricare il testo completo della Divina Commedia in un file di testo. lynx -dump http://www.filosofico.net/ladivinacommedia.htm

Si procede con l’eventuale modifica della codifica del documento, per evitare problemi di

interpretazione delle lettere accentate e di altri simboli, conviene convertire il documento nel formato

UTF-8.

Successivamente è necessario sostituire gli spazi tra le parole con un newline (a capo).

cat divina_utf8.txt | tr ' ' '\n'

Tuttavia sarebbe opportune eliminare dal testo anche i simboli di interpunzione: cat divina_utf8.txt | tr ' ,.;?-:«»()' '\n'

È possibile eliminare tutti i segni di interpunzione direttamente tramite uno specifico argomento del comando tr. L’esercizio chiede di trovare la parola più utilizzata nel testo, pertanto dopo la “pulitura” del testo, si procederà ad un primo ordinamento alfabetico ed all’eliminazione dei doppioni (un’opzione del comando uniq conterà le occorrenze di ogni parola), in seguito si applicherà un ordinamento numerico (l’opzione nr del comando sort) e si applicherà la paginazione al risultato. Il comando completo sarà analogo al seguente: cat divina_utf8.txt | tr [:punct:] '\n' | tr ' ' '\n' | sort | uniq -c | sort -nr | less

65 Lynx - http://it.wikipedia.org/wiki/Lynx_(software) 66 Lynx Browser - http://lynx.isc.org/current/

Page 33: Appunti del corso di Sistemi Operativi

33

Esercizi Costruire uno script che disegni verticalmente una sinusoide continua la cui frequenza viene

fornita come parametro. #!/bin/bash if [ $# -ne 1 ]; then echo 'Usage export COLUMNS; ./sinusoide.sh frequenza'; exit; fi if [ -z $COLUMNS ]; then echo 'Usage: export COLUMNS; ./sinusoide.sh frequenza'; exit; fi ampiezza=$(( COLUMNS/2 )) frequenza=$1 t=0; while true; do b=$(echo "c=$ampiezza*s($frequenza*$t*3.14/180);scale=0; $ampiezza + c/1" | bc -l); for (( a = 1; a < b; a++ )); do echo -n " "; done; echo '*'; ((t++)) done

Costruire uno script che stampi la percentuale della CPU utilizzata dal comando del quale viene

fornito il PID. #!/bin/bash pid=$1 #scale=${2:-2} # this line is an alternative to the following echo ${scale:=2} > /dev/null while true; do cpu=$(ps -p $pid -o%cpu= | tr , .) sleep 0.05 b=$(echo "c=$scale*$cpu;scale=0; c/1" | bc -l); for (( a = 1; a < b; a++ )); do echo -n "-"; done; echo '*'; done

Page 34: Appunti del corso di Sistemi Operativi

34

Ulteriori informazioni sui processi Quando si lancia un comando, avvengono due fasi:

1. FORK67: bash si duplica, copia variabili, stato della memoria

2. EXEC68: prende come argomento il file eseguibile sul disco, lo esegue, prende i dati (variabili,

ecc) del file eseguibile.

È possibile trasformare il bash corrente nel comando indicato, inserendo un comando analogo al

seguente:

exec nomecomando

Ad esempio “ls”: exec ls

Esistono due tipi di comandi:

COMANDI SU DISCO

SHELL BUILTIN

I comandi su disco prevedono la creazione di un processo mediante fork ed exec.

Un comando builtin viene eseguito direttamente da bash.

È possibile verificare se un comando è dell’uno o dell’altro tipo, utilizzando il comando type:

which echo type echo type cp type sleep

/bin/echo echo is a shell builtin cp is /bin/cp sleep is /bin/sleep

Il comando type restituirà il percorso del file

eseguibile, qualora si tratti di un comando su

disco.

Quando un processo parte ha una sua memoria

(virtuale), ogni processo è convinto di avere a

disposizione il massimo della memoria

indirizzabile.

In un sistema a 32 bit, la memoria totale

indirizzabile è 232, cioè 4 GB.

Lo swapping 69consiste nell’utilizzo di spazio su disco come spazio temporaneo per la memoria dei processi non attivi. Una rappresentazione della memoria:70

67 Fork: http://en.wikipedia.org/wiki/Fork_(operating_system) 68 Exec: http://en.wikipedia.org/wiki/Exec_(operating_system) 69 Swap: http://it.wikipedia.org/wiki/Swap_(informatica) 70 GaPiL - pg. 25 - http://gapil.gnulinux.it/files/2011/12/gapil.pdf

Page 35: Appunti del corso di Sistemi Operativi

35

Comando Descrizione

vmmap Virtual Memory Map vmmap $$ Virtual Memory Map di Bash

Alcuni comandi su Linux

cd /proc cat cpuinfo ls cd $$ ls -lad cwd cat environ cat maps

Process information pseudo-filesystem71 Visualizza informazioni sulla CPU Visualizza i file presenti nella cartella /proc Vai alla directory corrispondente al bash Informazioni sulla Current Working Directory Variabili d’ambiente associate al processo corrente Visualizza una mappa della memoria

Comando Descrizione

free Visualizza lo stato della memoria (Totale/Utilizzata/Libera) pmap PID Librerie utilizzate da un processo (funziona solo a runtime) pmap $$ Librerie utilizzate dal processo Bash ldd /bin/bash Visualizza le dipendenze di un processo72 (anche a processo non

avviato) size /bin/bash Visualizza le dimensioni vmstat Visualizza lo stato della memoria virtuale printf Funzione simile alla printf del linguaggio C73 Esistono directory che hanno lo sticky bit, esso è necessario in cartelle utilizzate da molti utenti affinché ogni utente possa cancellare i propri file e non quelli degli altri. Per trovare le cartelle che hanno impostato lo sticky bit, eseguiamo il comando: find / -type d -perm +1000 2>/dev/null

Le directory hanno inoltre il privilegio di esecuzione: tale permesso è denominato search bit, in quanto consente di accedervi per ricercare file. Per verificare, eseguire il comando: ls -lad nomecartella

Comando Descrizione

du . Disk Usage - Cartella corrente du nomefile Disk usage - File indicato, se il file è vuoto occupa 0 blocchi su disco gzip -r nomecartella Comprimi la cartella indicata74 gunzip Decomprimi

71 http://it.wikipedia.org/wiki/Procfs 72 Shared Library Dependencies - http://man.cx/ldd 73 http://man.cx/printf 74 Comandi gzip e gunzip : http://man.cx/gzip

Page 36: Appunti del corso di Sistemi Operativi

36

Altri comandi Comando Descrizione

nice nomeprogramma Il comando abbassa la priorità del processo exec nomeprogramma Sostituisce allo shell in uso lo script lanciato con il comando exec ls 1>filetemp.txt Sostituisce allo shell il comando ls il cui output viene salvato in

filetemp.txt Per trovare tutti i softlink presenti in home si esegue: find ~ -type l | less

Il comando seguente restituisce il percorso del file a cui punta il softlink: readlink "/percorso/cartella/nomelink"

Segnali I segnali sono “Software Interrupt”, cioè un segnale appunto o un messaggio che avvisa circa il

verificarsi di un certo evento. Esistono due tipi di segnali75: sincroni e asincroni.

Quando ad esempio un utente preme la combinazione di tasti CTRL-C viene generato un segnale che forza l’interruzione di un processo. Il kernel invia al processo un segnale, il processo, una volta ricevuto il segnale può scegliere uno dei tre comportamenti disponibili:

DEFAULT: generalmente “terminate process” IGNORARE IL SEGNALE: il segnale viene quindi ignorato ed il processo continua l’esecuzione GESTIRE IL SEGNALE: il processo gestisce il segnale mediante un Signal Handler

Il segnale 17 non può essere gestito [SIGSTOP].

Gestire i segnali È possibile gestire i segnali mediante il comando trap del quale segue la formattazione: trap [-lp] [arg] [sispec ...]

Il comando arg è da leggere e da eseguire quando la shell riceve il segnale sigspec. Se arg è assente oppure -, tutti gli specifici segnali sono reimpostati ai loro valori originali (i valori che avevano precedentemente all’ingresso nella shell). Se arg è la stringa nulla il segnale specificato da ogni sigspec è ignorato dalla shell e dal comando che invoca. Se arg non è presente ed è fornito -p, i comandi trap associati con ogni sigspec sono visualizzati. Se non vengono forniti argomenti o se è dato solo -p, trap stampa la lista dei comandi associati con ogni numero di segnale. 76

Comando Descrizione

trap ls SIGINT Ad ogni segnale SIGINT (che si genera premendo CTRL-C) esegue il comando ls

trap -p Visualizza tutti i segnali gestiti trap - SIGINT Annulla le impostazioni definite per il segnale SIGINT ulimit -a Visualizza i limiti della macchina in uso

75 Segnali: http://it.wikipedia.org/wiki/Segnale_(informatica) 76 Comando trap - Manuale di Bash: - http://man.cx/bash#heading31

Page 37: Appunti del corso di Sistemi Operativi

37

Segue una tabella dei segnali:

Signal Description Signal number on Linux x86[1]

SIGABRT Process aborted 6 SIGALRM Signal raised by alarm 14 SIGBUS Bus error: "access to undefined

portion of memory object" 7

SIGCHLD Child process terminated, stopped (or continued*)

17

SIGCONT Continue if stopped 18 SIGFPE Floating point exception: "erroneous

arithmetic operation" 8

SIGHUP Hangup 1 SIGILL Illegal instruction 4 SIGINT Interrupt 2

SIGKILL Kill (terminate immediately) 9 SIGPIPE Write to pipe with no one reading 13 SIGPOLL Pollable event 29 SIGPROF Profiling timer expired 27 SIGQUIT Quit and dump core 3 SIGSEGV Segmentation violation 11 SIGSTOP Stop executing temporarily 19 SIGSYS Bad syscall 31

SIGTERM Termination (request to terminate) 15 SIGTRAP Trace/breakpoint trap 5 SIGTSTP Terminal stop signal 20 SIGTTIN Background process attempting to

read from tty ("in") 21

SIGTTOU Background process attempting to write to tty ("out")

22

SIGURG Urgent data available on socket 23 SIGUSR1 User-defined 1 10 SIGUSR2 User-defined 2 12

SIGVTALRM Signal raised by timer counting virtual time: "virtual timer expired"

26

SIGXCPU CPU time limit exceeded 24 SIGXFSZ File size limit exceeded 25

Il segnale SIGSTOP stoppa il processo Il segnale SIGCONT riprende il processo

Segnale Combinazione di tasti

SIGTSTP CTRL-Z SIGQUIT CTRL-\ SIGINT CTRL-C

Page 38: Appunti del corso di Sistemi Operativi

38

Il comando Kill

Il comando kill77 serve per inviare segnali. Segue la sintassi del comando:

kill [-s sigspec | -n signum | -sigspec ][pid | jobspec]...

kill -l [sigspec | exit_status]

Alcuni esempi: kill -SIGINT PID kill -SIGINT 2264 kill -SIGKILL $$ kill -SIGSTOP 57348 kill -SIGCONT 57348

Invia il segnale SIGINT al processo indicato Invia il segnale SIGINT al processo 2264 Invia il segnale SIGKILL (Termina) al bash corrente Invia il segnale SIGSTOP (Stoppa) al processo 57348 Invia il segnale SIGCONT (Riprendi) al processo 57348

Ricerca nel computer In MacOS X esiste un motore di ricerca integrato, denominato Spotlight78 che consente di effettuare

ricerche approfondite tra i file presenti sul computer ed all’interno del contenuto dei file stessi.

Spotlight dispone di un indicizzatore istantaneo. Esiste una versione del motore di ricerca, disponibile dalla riga di comando, il comando mdfind79

Comando Descrizione

mdfind -0 Separa i risultati mediante NULL (per manipolarli con xargs) mdfind -onlyin cartella Restringe la ricerca ad una specifica cartella mdfind -live Il comando continua a girare, aggiorna i risultati in tempo reale mdls nomefile Restituisce i metadati del file strings nomefile Visualizza le stringhe di un file binario mdfind consente anche di eseguire ricerche in base ai metadati di un file. Il comando seguente cercherà tutti i file di immagine la cui altezza in pixel sarà inferiore a 500 pixel. mdfind 'KMDItemPixelHeight<500'

Il comando seguente cercherà tutti I file di imagine la cui altezza in pixel è compresa tra 440 e 500 pixel: mdfind 'KMDItemPixelHeight<500 && KMDItemPixelHeight>440'

Il comando seguente, uguale al precedente, manipolerà l’output restituendo l’altezza in pixel di ogni immagine trovata ed eseguirà un ordinamento dell’output. mdfind 'KMDItemPixelHeight<500 && KMDItemPixelHeight>440' | xargs -0 mdls -name\ KMDItemPixelHeiht | sort -n

77 Kill - Terminate or signal processes - http://man.cx/kill 78 Apple Spotlight - http://en.wikipedia.org/wiki/Spotlight_(software) 79 Ulteriori informazioni su mdfind - http://macdevcenter.com/lpt/a/6403

Page 39: Appunti del corso di Sistemi Operativi

39

Tubi a T È possibile costruire dei tubi “a T”, per estrarre il risultato di un comando, tra due pipe, così da poter

manipolare il risultato “intermedio” dei comandi.

Il comando tee serve per costruire questo tipo di tubi, come nell’esempio:

ps -ef | tee uscitatubo.txt | grep bash

Altri comandi Sed è un linguaggio di scripting, un suo utilizzo interessante è la sostituzione di caratteri.

echo casa | sed s/sa/ma Restituirà “cama”, sostituirà la sillaba “sa” con “ma”

Il comando jot genera una serie di dati sequenziali o casuali. Comando Descrizione

jot 25 0 9 25 numeri compresi tra 0 e 9, incremento di default 1 jot 25 0 25 numeri compresi tra 0 e 24 jot -r 25 0 25 numeri casuali, partendo da 0 jot -r 25 0 1000 25 numeri casuali, compresi tra 0 e 1000 jot -r -c 100 a z 100 caratteri casuali (a-z) Il comando rs serve per dare forma ad un array di dati, combinandolo con jot è possibile ottenere dei dati casuali e formattarli in un modo specifico. Per visualizzare 1000 caratteri casuali, organizzati in una matrice 4x4, il comando sarà: jot -r -c 1000 a z | rs 4 4

Il comando rs è seguito dal numero di righe e dal numero di colonne. Per organizzare i dati in 20 colonne ed eliminare gli spazi di divisione del contenuto: jot -r -c 1000 a z | rs -g 0 20

Formare parole casuali e verificarne l’eventuale esistenza nel dizionario: jot -r -c 10000 a z | rs -g 0 4 | xargs -I % grep ^%$ italian

Il comando dd80 serve per copiare e convertire un file, nell’esempio prendere il “fileinput.txt” e ne crea una copia, scegliendo le prime 3 lettere dalla prima riga. dd ibs=1 obs=1 count=3 skip=3 if=fileinput.txt of=fileoutput.txt

Dato che la prima parola di “fileinput.txt” è “Achille” il file di destinazione “fileoutput.txt” conterrà “ill”.

80 Convert and Copy a File - http://man.cx/dd

Page 40: Appunti del corso di Sistemi Operativi

40

Comando Descrizione

df Visualizza i filesystem montati echo 4 | tr \\064 d Sostituisce con un range ottale echo 45678 | tr \\064 - \\067 defgh Sostituisce con un range ottale tr -d \\000 - \\037 Elimina tutti i caratteri da 0 a 37 ottale

Comando Descrizione

fuser nomefile Lista dei PID che hanno aperto il file “nomefile” lsof -p PID Quale file ha aperto un processo o una lista di processo lsof Lista i file aperti da tutti i processi

Differenze tra i file Per trovare le differenze tra due file c’è il comando diff diff nomefile1 nomefile2 diff nomefile1 nomefile2 > patch

Restituisce le differenze (20a21,22) Salva in un file le differenze tra due file

È possibile “patchare” un file utilizzando il comando patch, utile per aggiornare un file all’ultima versione. patch nomefile filepatch Applicherà “filepatch” al file “nomefile”

È possibile confrontare due file utilizzando il comando cmp81, indicato per il confronto di file binari. Comando Descrizione

killall nomedelprocesso Chiude tutte le istanze del processo killall nano Chiude tutte le istanze dell’editor nano killall TextWrangler Chiude tutte le istanze di TextWrangler

Strumenti di rete

Comando Descrizione

open http://www.liis.it Apri la pagina www.liis.it curl http://www.liis.it Restituisce il codice HTML della pagina ping 193.204.64.3 Esegui ciclicamente il ping dell’IP indicato (CTRL+C per

bloccare) ping -q 193.204.64.3 Verifica l’esistenza di una macchina ifconfig Visualizza le informazioni sulle interfacce e le

connessioni di rete sul PC netstat Statistiche sulle connessioni di rete netstat -f inet Filtra ciò che riguarda le connessioni internet netstat -f inet -p tcp Connessioni internet attive netstat -b -I en0 -f inet -p tcp Connessioni aperte dall’interfaccia en0 whois 193.204.64.3 Visualizza informazioni sul proprietario dell’indirizzo IP

81 Compare Files - http://man.cx/cmp

Page 41: Appunti del corso di Sistemi Operativi

41

Per visualizzare tutte le interfacce di rete del PC: ifconfig -a

Creare uno script che da ifconfig -a tiri fuori tutti gli indirizzi IP utilizzati dalla macchina: #!/bin/bash for i in $(ifconfig -a | grep UP | cut -d: -f1); do ifconfig $i | grep '\binet\b' done | cut -d' ' -f2

Shell Builtin di Bash

Comando Descrizione

source Equivalente di #include del linguaggio C Include un file all’interno del comando che si sta eseguendo

break Serve per uscire dal loop (ad esempio while) set -x Dopo l’espansione dei comandi semplici, visualizza

l’espansione del prompt quaternario PS4, seguito dal comando ed i suoi argomenti espansi. Fa vedere cosa viene eseguito e mostra l’espansione degli argomenti, se un comando contiene la variabile, fa vedere il valore della variabile (come una modalità di debug)

set +x Disattiva la modalità set -x

Scrivendo: set -x for i in 1 2 3 4 5 6 > do > echo $i > done

si otterrà l’espansione del commando ed il risultato, ad esempio: + for i in 1 2 3 4 5 6 + echo 1 1 + echo 2 2 + echo 3 3 + echo 4 4 + echo 5 5 + echo 6 6

Page 42: Appunti del corso di Sistemi Operativi

42

Ricerca avanzata

Visualizzare il numero dei file presenti in una cartella:

find /path/nomecartella -type f | wc -l

Cercare tutti i file con estensione .c in una cartella:

find /path/nomecartella -name \*.c | wc -l

Per cercare sia i file .h sia quelli .c:

find /path/nomecartella -name \*.h -or -name \*.c | wc -l

Nel caso di espressioni composte è necessario utilizzare le parentesi:

find /path/nomecartella \(-name \*.h -or -name \*.c\) | wc -l

Page 43: Appunti del corso di Sistemi Operativi

43

Sviluppo del software

Un esempio di programma in linguaggio C, il file tombola.c

#include <stdio.h> #include <sys/types.h> #include <unistd.h> /*Programma per la estrazione di 90 numeri di tombola.*/ int main(int argc,char **argv) { int n, m, nread, a=1; int tab[91]; char buffer[128]; pid_t pid = getpid(); /* Get our process ID */ srand((unsigned)pid); for (n=1; n<=90; n++ ) { tab[n] = 0; } for ( n=1; n<=10; n++ ) { printf("\n"); fflush(stdout); } m = 0; printf("Premi <Invio> per un'estrazione o Ctrl-C per uscire.\n"); while (a) { n = rand() % 90 + 1; /* 1 to 90 */ /* printf("%d\t%d.\n", n, tab[n]);*/ printf(""); if (tab[n]) { } else { tab[n] = 1; m++; nread = read(0,buffer,128); printf("L'estrazione numero %d e' \t%d.\n", m, n); for ( n=1; n<=10; n++ ) { printf("\n"); fflush(stdout); } }; if (m > 89) {a = 0;} } }

Page 44: Appunti del corso di Sistemi Operativi

44

Comando Descrizione

whereis gcc Visualizza la posizione di GCC, si tratta di un softlink a gcc, il compilatore GNU/Linux per il linguaggio C

info gcc Apre una guida in formato pseudo-ipertesto, non si tratta di una struttura flat come il man, ma di un modello di ipertesto primordiale. Il tasto Invio consente di aprire un link (contrassegnato da *), q chiude il manuale, b torna all’inizio

Il compilatore ha una lunga serie di opzioni. Su MacOS X si può compilare con gcc ad esempio software

per un Atari, per altri processori ed altre architetture (Cross Comiling).

In alcune pagine di manuale è riportata la dicitura “Fare riferimento alla documentazione mantenuta in

formato info”, è il caso di gcc, la cui guida in formato info presenta contenuti più aggiornati.

Alcune risorse utili:

Manuale del Preprocessore C - http://gcc.gnu.org/onlinedocs/cpp/

Manuale del Compilatore GCC - http://gcc.gnu.org/onlinedocs/gcc/

Per inviare comandi al preprocessore si utilizza #

Per compilare un programma non sono necessarie opzioni aggiuntive, infatti è sufficiente far seguire il

nome del file sorgente al comando gcc. Dopo la compilazione viene prodotto un eseguibile

denominato a.out

Per evitare che l’eseguibile si chiami a.out è possibile utilizzare uno switch del compilatore (con il

termine switch si indica un’opzione del compilatore).

Comando Descrizione

gcc tombola.c Compila il programma tombola.c, l’eseguibile sarà a.out gcc tombola.c -o tombola Compila il programma tombola.c, l’eseguibile sarà tombola gcc sorgente.c -o destinazione Compila il programma sorgente.c, l’eseguibile sarà

destinazione

In Unix i file di intestazione sono contenuti nella cartella di default: /usr/include Per cercare, ad esempio, in quale file d’intestazione si trova la funzione printf è sufficiente eseguire: grep -r printf /usr/include 2>/dev/null | wc

Si otterranno moltissimi risultati poiché il comando cercherà tutte le parole che contengono la stringa “printf”, si può raffinare la ricerca: grep -r '\bprintf\b' /usr/include 2>/dev/null | wc

Si scoprirà quindi che:

/usr/include contiene i prototipi delle funzioni

/usr/lib contiene le funzioni vere e proprie

Si può ancora migliorare la ricerca:

grep -r '\bprintf\b' /usr/include 2>/dev/null | grep '\bint\b' |wc

Page 45: Appunti del corso di Sistemi Operativi

45

E si otterranno 13 risultati. In essi compaiono anche quelli contenenti la stringa “_printf” poiché il

carattere underscore è considerato separatore di parola. La ricerca può essere perfezionata ancora:

grep -r ' \bprintf\b' /usr/include 2>/dev/null | grep '\bint\b' |wc

Si otterrà dunque che la funzione printf è dichiarata nel file stdio.h

Analogamente si può cercare quale file di intestazione contiene la dichiarazione della funzione srand:

grep -r '\bsrand\b' /usr/include 2>/dev/null | wc

Ottenendo che srand è definita nel file stdlib.h

Tornando al file tombola.c, si può notare che pur utilizzando la funzione srand, non sono stati inclusi

riferimenti al file stdlib.h, ma è molto probabile che qualche libreria allegata includa il file

stdlib.h

Esiste uno strumento in gcc che consente di vedere tutte le librerie caricate da un file, la catena degli

include:

gcc -H tombola.c

Restituirà tutte le librerie incluse, visualizzate con un annidamento ad albero:

. /usr/include/stdio.h

.. /usr/include/_types.h

... /usr/include/sys/_types.h

.... /usr/include/sys/cdefs.h

.... /usr/include/machine/_types.h

..... /usr/include/ppc/_types.h

. /usr/include/sys/types.h

.. /usr/include/sys/appleapiopts.h

.. /usr/include/machine/types.h

... /usr/include/ppc/types.h

.... /usr/include/ppc/_types.h

.. /usr/include/machine/endian.h

... /usr/include/ppc/endian.h

.... /usr/include/sys/_endian.h

.. /usr/include/sys/_structs.h

. /usr/include/unistd.h

.. /usr/include/sys/unistd.h

.. /usr/include/sys/select.h

... /usr/include/sys/_structs.h

... /usr/include/sys/_select.h

Si può notare che non è inclusa la libreria stdlib.h, tuttavia è importante ricordare che se una funzione

non è stata definite, il C suppone che abbia un’uscita intera e che non abbia variabili.

Ovviamente, per non avere risultati inattesi, è importante controllare sempre che una funzione sia

definita o che siano corretti i riferimenti di inclusione dei file che contengono la relativa definizione di

funzione.

È possibile fare in modo che il compilatore aiuti nella scelta delle librerie da includere nel sorgente,

per fare ciò è necessario attivare i Warnings nel compilare, cioè la visualizzazione degli avvisi relativi

alla compilazione dei file.

Page 46: Appunti del corso di Sistemi Operativi

46

gcc -Wall tombola.c -o tombola

L’opzione -W attiva i warnings, inoltre è necessario specificare il livello di warnings desiderato: all

mostrerà tutti i gli avvisi.

Compilando il file tombola.c, il compilatore restituirà ora degli avvisi relativi alla “dichiarazione

implicita delle funzioni srand e rand”.

I programmi così compilati non sono adatti al debugging, il debug si esegue con GDB (GNU Debugging)

che consente di scovare facilmente gli errori nei programmi C.

Esiste un’opzione per compilare un programma in modo che si possa successivamente eseguire il

debug:

gcc -g sorgente.c -o destinazione

Make ed il file Makefile I programmi C scritti da un principiante sono generalmente composti da un singolo file, il C però

incoraggia a dividere il proprio codice sorgente in più file, è frequente infatti che un progetto di piccole

dimensioni sia suddiviso in numerosi file.

Non è necessario che, in caso di modifica ad un singolo file, tutti i file debbano essere riprocessati per

costruire l’eseguibile. In molti casi infatti è sufficiente compilare un file .o (detto Object File).

Esiste inoltre un albero delle dipendenze.

Uno strumento, in presenza di modifiche ai prerequisiti (file di partenza), apporta le modifiche

esclusivamente alla parte interessata. Questo strumento è MAKE ed è stato creato dalla GNU

Foundation.

Quando si scarica un software Open Source, in genere si scaricano in sorgenti che devono essere

compilati sulla macchina in uso e per fare ciò è necessario conoscere ed utilizzare MAKE.

Make utilizza un file denominato Makefile (o MAKEFILE, una lista di dipendenze e di regole per

l’esatta risoluzione di queste dipendenze; quando si avvia MAKE, esso verifica nella Current Working

Directory l’esistenza del file Makefile. Tale file deve essere strutturato in una certa maniera,

seguendo una specifica sintassi.

Il secondo rigo del Makefile deve iniziare con un tabulatore, in caso di assenza, non funzionerebbe.

Tra la regola (1° riga del file) e la dipendenza (2° riga) non devono esserci righe vuote.

Esempio di Makefile:

testo : pezzo1.txt pezzo2.txt pezzo3.txt cat pezzo1.txt pezzo2.txt pezzo3.txt > testo.txt pezzo1.txt : sottopezzo1-1.txt sottopezzo2-1.txt cat sottopezzo1-1.txt sottopezzo2-1.txt > pezzo1.txt pezzo2.txt : sottopezzo1-2.txt sottopezzo2-2.txt cat sottopezzo1-2.txt sottopezzo2-2.txt > pezzo2.txt pezzo3.txt : sottopezzo1-3.txt sottopezzo2-3.txt cat sottopezzo1-3.txt sottopezzo2-3.txt > pezzo3.txt

Page 47: Appunti del corso di Sistemi Operativi

47

Scrivendo a terminale:

make testo

Il compilatore seguirà le dipendenze e compilerà il file.

Make verifica la data dei file (dei vari sottopezzi) e se trova una data successiva a quella del file

compilato, compila la parte necessaria.

Il programma make vale in generale, ad esempio potrebbe essere utilizzato da una redazione che ha un

programma per assemblare gli articoli dei vari giornalisti e restituisce il giornale impaginato.

Inoltre se si scrive make tombola , make trova il file tombola.c (se presente nella CWD) e presume si

voglia compilare il file. Nel caso in cui il file eseguibile sia presente ed aggiornato, il programma

restituirà:

make: 'tombola' is up to date.

Modificando il file tombola.c e rilanciando il comando

make tombola

Make intuisce euristicamente che si debba compilare il file C, lanciando automaticamente il comando:

cc tombola.c -o tombola

Make riconosce una serie di linguaggi di programmazione di default.

Per approfondimento si rimanda al libro “Advanced Programming in the Unix Environment”82

In un makefile:

DIRS = definizione... Definizione di macro, tutto ciò che è a destra dell’uguale $(DIRS) Utilizzo delle variabili proprie di make $$i Utilizzo delle variabili dello shell

È possibile che in un makefile ci siano i target ma non i prerequisiti.

Un esempio:

all: $(MAKE) ‘./systype.sh’ macos: for i in $(DIRS); do \ (cd $$i && $(MAKE) -f macos.mk ) || exit 1; \ done

Con il comando seguente, si indica al make di utilizzare un makefile alternativo

make -f

82 Advanced Programming in the Unix Environment - http://www.apuebook.com

Page 48: Appunti del corso di Sistemi Operativi

48

Un esempio di makefile alternativo:

include ../Makefile.defines.macos PROGS = access cdpwd all: ${PROGS} savedid: savedid.o $(LINK.c) -o savedid.o $(LDLIBS)

Segue ora un esempio di definizioni comuni del make adattate per un sistema Mac OS X.

WKDIR=/Users/nomeutente/Documents/PSR2012/apue.2e CC=gcc COMPILE.c=$(CC) $(CFLAGS) $(CPPFLAGS) -c LINK.c=$(CC) $(CFLAGS) $(CPPFLAGS) $(LDDIR) $(LDFLAGS) LDDIR=-L../lib LDLIBS=../lib/libapue.a CFLAGS=-ansi -I$(WKDIR)/include -Wall -DMACOS $(EXTRA) #Our library that almos every program needs LIB=../libapue.a # Common temp files to delete from each directory TEMPFILES=core core.* *.o temp.* *.out typescript*

La compilazione produce dei file .o, cioè file oggetto.

GCC per impostazione predefinita esegue anche il linking del programma, utilizzando invece l’opzione

-c , gcc si limiterà alla sola compilazione dei file oggetto, non eseguendo il linking.

Con la macro seguente infatti, si impedirà a gcc l’esecuzione del linking:

COMPILE.c=$(CC) $(CFLAGS) $(CPPFLAGS) -c

Nel caso presentato, il linking viene ridefinito con una riga specifica, nella quale si indica al linker dove

trovare le librerie personalizzate.

LINK.c=$(CC) $(CFLAGS) $(CPPFLAGS) $(LDDIR) $(LDFLAGS)

L’utente non può inserire le proprie librerie nella directory /usr/lib ; in questa cartella (default per le

librerie) solo l’amministratore del sistema può aggiungere nuove librerie.

Nell’esempio presentato sono stati definiti tutti i flags da utilizzare nella compilazione, in particolare

con la riga:

CFLAGS=-ansi -I$(WKDIR)/include -Wall -DMACOS $(EXTRA)

Dove con -ansi si impone al compilatore l’utilizzo dello Standard C, infatti non saranno accettati

sorgenti che non saranno conformi con lo standard ANSI C.

Page 49: Appunti del corso di Sistemi Operativi

49

Le direttive del preprocessore possono essere passate da riga di comando con l’opzione -D,

nell’esempio infatti si nota: -DMACOS $(EXTRA)

Make si blocca al primo errore incontrato e non esegue il resto delle operazioni, per continuare

l’esecuzione anche in caso di errori è necessario utilizzare l’opzione -i

make -i

Debug Per eseguire il debug di un file è necessario compilarlo utilizzando una specifica modalità:

cc -ggdb tombola.c -o tombola

Per aprire il file in modalità debugging, eseguire:

gdb ./tombola

All’interno del debugger è possibile utilizzare una lista di comandi:

Comando Descrizione

l Comando LIST, visualizza il sorgente C del programma (prime 10 righe). La ripetizione del comando consente di avanzare tra le righe del programma.

b 20 Inserisce un breakpoint (punto d’interruzione nel programma) alla riga 20, vuol dire che il debugger eseguirà il programma fino alla riga 24 esclusa.

p nomevariabile È possibile verificare il nome di una variabile scrivendo il comando p seguito dal nome di una variabile

p &nomevariabile Visualizza l’indirizzo di memoria della variabile “nomevariabile”

s Comando STEP, esegue l’istruzione successiva e mostra al terminale la prossima

clear 20 Elimina il breakpoint creato alla riga 20

Comandi vari

Comando Descrizione

ssh hplinux2.unisalento.it ls Esegue il comando ls sulla macchina remota ssh hplinux2.unisalento.it 'ps -e' Esegue il comando ps -e sulla macchina remota ssh hplinux2.unisalento.it 'uptime' Carico medio del sistema sulla macchina remota stty -echo Scrivi senza che il testo inserito sia visibile stty echo Ripristina l’echo stty -a Visualizza tutte le associazioni

Page 50: Appunti del corso di Sistemi Operativi

50

Comando Descrizione

whereis sh Restituisce il percorso di sh: /bin/sh

ls -la /bin/sh Restituisce le informazioni su /bin/sh -r-xr-xr-x 1 root wheel 1244960 Jun 18 2009 /bin/sh

ls -lai /bin/sh Visualizza anche l’inode 1003466 -r-xr-xr-x 1 root wheel 1244960 Jun 18 2009 /bin/sh

ls -lai /bin/bash Informazioni su /bin/bash 1003420 -rwxr-xr-x 1 root wheel 1244928 Jun 17 2009 /bin/bash

Per visualizzare il numero di tutti gli script contenuti nella cartella /etc

Per visualizzare gli script shell (prima versione)

grep -r '#!/bin/sh' /etc 2>/dev/null | wc

Per visualizzare gli script bash

grep -r '#!/bin/bash' /etc 2>/dev/null | wc

Cerca tutti gli script SH e restituisce il nome

grep -r '#!/bin/sh' /etc 2>/dev/null

Esistono degli script periodici, situati nelle relative cartelle: daily, monthly, weekly.

L’esecuzione di tali script è regolata dal file periodic.conf

Per visualizzare tale file con TextWrangler:

edit /etc/defaults/periodic.conf

Il programma che esegue le azioni programmate è periodic

Comando Descrizione

whereis periodic Restituirà /usr/sbin/periodic

edit /usr/sbin/periodic Visualizzare il contenuto dello script

È possibile creare un file temporaneo scrivendo la riga:

mktemp ${TMPDIR:-/tmp}/periodic.XXXXXXXXXX

Il comando eval83 rivaluta l’espressione che lo segue; esegue un ulteriore giro di valutazione.

Quando si esegue il comando ps -ef per visualizzare la lista dei processi attivi, nell’output del

comando compaiono le colonne VSZ e RSZ che indicano:

83 Comando Eval - http://man.cx/eval

Page 51: Appunti del corso di Sistemi Operativi

51

Virtual Size Set (VSZ) - Memoria virtuale occupata da un processo

Real Size Set (RSZ) - Memoria reale occupata

Si deve tenere presente che, ad esempio, le librerie C sono allocate una sola volta per tutti i processi

che ne fanno richiesta, pertanto non sarà possibile effettuare un conteggio accurato di quanta memoria

occupa ciascun processo.

Con il comando top è possibile avere una visualizzazione dinamica dei processi con informazioni

dettagliate su ciascun processo attivo. È possibile avere una visualizzazione statica di top, eseguendo il

comando:

top -l1

Su MacOS X esiste il comando vmmap che produce una mappa della memoria virtuale.

Su GNU/Linux invece, esiste una mappa della memoria per ogni processo, infatti in /proc esiste un file

maps per ciascun processo attivo.

Il comando curl consente di visualizzare siti web all’interno del terminale, di estrarre dati da essi

oppure ancora, di visualizzare gli headers di una pagina web.

Comando Descrizione

curl http://www.google.it Restituisce il codice HTML della pagina web indicata curl -I http://www.google.it Restituisce gli Headers della pagina web indicata

È possibile reindirizzare l’output del comando curl, ad esempio per scrivere gli headers di una pagina

web all’interno di un file, così facendo, curl visualizzerà a terminale esclusivamente una statistica dei

dati scaricati (che viene inviata allo stderr) mentre scriverà nel file di testo indicato gli headers, come

nel comando seguente.

curl -I http://www.google.it 1>nomefile.txt

Conversione di date In alcune circostanze è utile convertire una data dal formato standard al formato in secondi a partire

da epoch (01/01/1970) così da poter eseguire semplicemente confronti oppure ordinamenti.

Si tenga presente che il formato di visualizzazione della data è condizionato dalle impostazioni sulla

localizzazione.

In Mac OS X per passare dall’output del comando date ad epoch, con localizzazione en-US

date -j -f "%a %b %d %T %Z %Y" "$(date)" +%s

In Mac OS X per passare dall’output del comando date ad epoch, con localizzazione it-IT

date -j -f "%a %b %d %Y %T %Z" "$(date)" +%s

Per verificare la localizzazione del terminale della macchina in uso, utilizzare il comando locale

Page 52: Appunti del corso di Sistemi Operativi

52

Su un terminale Linux per passare dall’output del comando date ad epoch, con localizzazione en-US

date -d "$(date)" +%s

L’output del comando:

ps -cax -opid,lstart

che visualizza l’istante di inizio di un processo, fornisce la data nel formato84:

"%a %m %b %T %Y

Per cui il comando di conversione in Mac OS X è:

date -j -f "%a %m %b %T %Y" "Dom 3 Apr 10:25:14 2011" +%s

Su un’altra macchina con localizzazione differente è:

date -j -f "%a %d %b %Y %T %Z" "$(date)" "+%s"

poiché il comando date restituiva: Mar 19 Giu 2012 15:34:06 CEST

Per far funzionare il comando con i risultati restituiti dal comando curl quando sono in inglese, è

possibile cambiare la localizzazione del tempo solo per l’esecuzione del comando:

LC_TIME="en_US.UTF-8" date -j -f "%a, %d %b %Y %T %Z" "Thu, 05 Jan 2012 18:12:40 GMT" "+%s"

Che risolve la seguente linea di header:

Last-Modified: Thu, 05 Jan 2012 18:12:40 GMT

in:

1325787160

Per modifica la localizzazione delle date:

Comando Descrizione

LC_TIME="en_US.UTF-8" Imposta la visualizzazione delle date in formato inglese USA LC_TIME="it_IT.UTF-8" Imposta la visualizzazione delle date in formato italiano

84 Fare riferimento al manuale del comando date - http://man.cx/date

Page 53: Appunti del corso di Sistemi Operativi

53

Per visualizzare la priorità dei processi attivi:

ps -e -o pid,nice,comm

Per conoscerla priorità del processo mdworker

ps -e -o pid,nice,comm | grep md

Tale processo, che si occupa dell’indicizzazione dei file presenti sul pc, ha una priorità (numero di

nice) pari a 17 su un massimo di 20, quindi priorità molto bassa. Il numero di nice è compreso tra -20

(priorità altissima) e 20 (priorità bassissima).

È possibile visualizzare la priorità dei processi anche utilizzando il comando seguente:

ps axl

Page 54: Appunti del corso di Sistemi Operativi

54

Simulazioni d’esame

Esercizio Scrivere in bash un loop che incrementi una variabile e stampare il valore di tale variabile dopo un

secondo.

contagiri.sh

#!/bin/bash i=0 trap 'echo $i; i=0' SIGUSR1 ./trigger.sh $$ & # lancia lo script, prende come argomento il PID del bash e lo pone in background while true do ((i++)) done

trigger.sh

#!/bin/bash while true do sleep 1 kill -SIGUSR1 $1 done

Esercizio Scrivere uno script bash in grado di fornire una rappresentazione grafica della bitmap degli inode

nel file system in cui si trova la propria home directory indicando con una 'x' gli inode occupati

e con un '.' quelli liberi.

Innanzitutto è bene conoscere qualche comando:

Comando Descrizione

df -k Visualizza i volumi montati df -i Volumi occupati, saranno visualizzati anche gli inode

È possibile visualizzare ad esempio un range di inode:

find / -inum +6070014 -inum -8538208 -exec stat -f%i {} \; 2>/dev/null

find / -inum 6070014 -exect stat -f%i {} \; 2>/dev/null

Page 55: Appunti del corso di Sistemi Operativi

55

E su Linux:

find / -inum +6359000 -inum -6360000 -exec stat -c%i {} \; 2>/dev/null

Si giungerà così allo script che risolve l’esercizio:

inodebitmap.sh

#!/bin/bash if [ $# -ne 2]; then echo 'Usage inodebitmap.sh inode_start how_many'; exit; fi inode_start=$1 inode_end=$(($1 + $2)) a=($(find / -inum +$inode_start -inum -$inode_end -exec stat -c%i {} \; 2>/dev/null)) for ((i=inode_start; i<=inode_end; i++)); do b[i]=.; done for i in ${a[*]}; do b[i]=x; done for ((i=inode_start; i<=inode_end; i++)); do echo ${b[i]}; done | rs -g 0 50

Un esempio di utilizzo:

./inodebitmap.sh 6359581 1000