Sei sulla pagina 1di 58

2011

SISTEMI OPERATIVI

Esame Laboratorio

Michele Mariani Universit degli Studi di Milano

Appunti strutturati come la modalit desame del Laboratorio di Sistemi Operativi tenuto dal professore Monga nellanno accademico 2011/12 Sono composti da: Introduzione: Comandi Unix e loro utilizzo generale Primo esercizio dellesame: Guida al partizionamento, secondo quanto visto da me a lezione durante lanno 11/12 Secondo esercizio dellesame: Guida allo Shell Scripting ( presa dal sito http://www.mrwebmaster.it/linux/guide/guida-shell-scripting/ e scritta da Massimiliano Bossi) Esempi di Esercizi Terzo esercizio dellesame: Esempi di esercizi

Sommario
COMANDI BASE ..................................................................................................................................... 3 GESTIONE DI FILE E DIRECTORY ..................................................................................................................... 3 Pwd ............................................................................................................................................................ 3 Ls ................................................................................................................................................................ 3 Cd ............................................................................................................................................................... 3 Mkdir ......................................................................................................................................................... 4 Cp ............................................................................................................................................................... 4 Mv .............................................................................................................................................................. 5 Rm e rmdir ................................................................................................................................................. 5 Touch ......................................................................................................................................................... 6 Ln ............................................................................................................................................................... 7 Chmod ....................................................................................................................................................... 7 FUNZIONI DI RICERCA .................................................................................................................................... 8 Find ............................................................................................................................................................ 8 Grep ........................................................................................................................................................... 8 GESTIONE DEL FILESYSTEM ........................................................................................................................... 9 Mount ........................................................................................................................................................ 9 Umount ...................................................................................................................................................... 9 OTTENERE INFORMAZIONI SUL SISTEMA .................................................................................................... 10 Du ............................................................................................................................................................ 10 Df ............................................................................................................................................................. 10 Free .......................................................................................................................................................... 11 Top ........................................................................................................................................................... 11 Uname ..................................................................................................................................................... 11 Lsb_release .............................................................................................................................................. 12 AMMINISTRAZIONE DEGLI UTENTI.............................................................................................................. 13 ALTRI COMANDI UTILI ................................................................................................................................. 14 Cat e less .................................................................................................................................................. 14 More ........................................................................................................................................................ 14 OTTENERE MAGGIORE AIUTO ..................................................................................................................... 15 ESERCIZIO 1 ......................................................................................................................................... 17 ESERCIZIO ESAME ........................................................................................................................................ 17 1

SVOLGIMENTO............................................................................................................................................. 17 Creazione disco ........................................................................................................................................ 17 Partizionamento ...................................................................................................................................... 17 Creazione filesystem................................................................................................................................ 20 Montare partizione.................................................................................................................................. 21 Smontare partizione ................................................................................................................................ 21 ESERCIZIO 2 ......................................................................................................................................... 23 GUIDA SHELL SCRIPTING.............................................................................................................................. 23 Introduzione allo shell scripting .............................................................................................................. 23 Il primo script........................................................................................................................................... 24 Le variabili ................................................................................................................................................ 25 Altri tipi di variabili .................................................................................................................................. 27 Wildcards e altri caratteri speciali ........................................................................................................... 29 Operatori ................................................................................................................................................. 30 Istruzioni di controllo: IF .......................................................................................................................... 32 Istruzioni di controllo: CASE .................................................................................................................... 34 I cicli for e while ....................................................................................................................................... 35 Scrivere una funzione .............................................................................................................................. 36 Conclusioni .............................................................................................................................................. 38 ESERCIZI TIPICI ............................................................................................................................................. 39 ESERCIZIO 3 ......................................................................................................................................... 51 CONSIGLI...................................................................................................................................................... 51 ESERCIZI TIPICI ............................................................................................................................................. 51

COMANDI BASE
GESTIONE DI FILE E DIRECTORY
Pwd Il comando pwd serve per mostrare la directory in cui ci si trova. La sintassi del comando la seguente: pwd [opzioni] Ls Il comando ls serve per elencare il contenuto di una directory. La sintassi del comando la seguente: ls [opzione] [directory] Alcune opzioni da utilizzare con il comando ls: Opzione [directory] -a -l -R -s -S -u -X -r --color Cd Il comando cd serve per spostarsi all'interno delle directory del filesystem. La sintassi del comando la seguente: cd [directory] Alcuni esempi di uso del comando:

Risultato elenca il contenuto della directory specificata, se non specificata viene considerata la directory corrente elenca anche i file nascosti elenco dettagliato di file e sotto directory con i loro attributi elenca ricorsivamente i file nella directory indicata e in tutte le sottodirectory mostra la dimensione dei file ordina i file per dimensione partendo dal pi grande ordina i file per data e ora di accesso partendo dal pi recente ordina i file per estensione e ordine alfabetico elenca i file invertendone l'ordine mostra i file con colori differenti

cd .. 3

Serve per spostarsi alla directory superiore.

cd Serve per spostarsi, da qualsiasi punto, alla propria directory home. equivalente a: cd ~

cd /etc Serve per spostarsi nella directory /etc.

Mkdir Il comando mkdir serve per creare directory all'interno del filesystem. La sintassi del comando : mkdir [opzioni] directory Alcuni esempi di uso del comando mkdir:

mkdir prova Verr creata la directory prova/ all'interno della directory corrente.

mkdir ~/prova Verr creata la directory prova all'interno della propria home directory, qualunque sia la directory in cui ci si trova al momento.

mkdir -p prova1/prova2/prova3/bin Qualora non esistessero, verranno create anche tutte le directory intermedie, a partire dalla directory corrente.

Cp Il comando cp serve per:


copiare copiare copiare copiare

un file in un altro file; un file in un'altra directory; pi file in un'altra directory; directory.

La sintassi del comando la seguente: cp [opzioni] origine destinazione Alcune opzioni da utilizzare con il comando cp: Opzione -b 4 Risultato esegue automaticamente una copia di backup di ogni file di destinazione esistente

-f -i -p -r -v

forza la sovrascrittura dei file, senza richiedere interventi da parte dell'utente attiva la modalit interattiva, che chiede conferma prima dell'eventuale sovrascrittura di file preesistenti mantiene, se possibile, gli attributi del file permette di attivare la modalit ricorsiva, consentendo la copia di directory attiva la modalit "verbose", visualizza ci che il sistema ha fatto in seguito al comando

Alcuni esempi di uso del comando cp:

cp /prova/miofile /prova1 Copia il file miofile della directory prova nella directory /prova1.

cp /prova/miofile /prova1/nuovofile Copia il file miofile della directory /prova nella directory /prova1 dandogli il nome nuovofile.

cp -r /prova /prova_copia Copia la cartella /prova, e tutto il suo contenuto, nella cartella /prova_copia.

Mv Il comando mv serve per spostare, o rinominare, file e directory. La sintassi del comando la seguente: mv [opzioni] origine destinazione Le opzioni sono le stesse del comando cp. Alcuni esempi di uso del comando mv:

mv miofile nuovofile Cambier il nome al file miofile in nuovofile. mv miofile /prova Sposter il file miofile nella directory /prova sovrascrivendo un eventuale file con lo stesso nome.

mv /prova /prova_nuova Cambier il nome alla directory /prova in /prova_nuova.

Rm e rmdir Il comando rm serve per cancellare file o directory dal file system. La sintassi del comando la seguente: rm [opzioni] file ... 5

Alcune opzioni da utilizzare con il comando rm: Opzione -i -f -r chiede conferma prima di cancellare forza la cancellazione del file senza chiedere conferma abilita la modalit ricorsiva usata per la cancellazione delle directory Risultato

Il comando rmdir serve per cancellare directory dal file system. La sintassi del comando la seguente: rmdir directory Alcuni esempi di uso dei comandi rm e rmdir:

rm miofile Cancella il file miofile. rm -rf prova/ Cancella la directory prova/ e tutto il suo contenuto. rmdir prova/ Cancella la directory prova/ solo se questa non contiene alcun file all'interno.

Touch Il comando touch serve per aggiornare la data dell'ultimo accesso o quello dell'ultima modifica di un file. La sintassi del comando la seguente: touch [opzioni] file Alcune opzioni da utilizzare con il comando touch: Opzione -a -c -m cambia solo la data dell'ultimo accesso non creare il file cambia solo la data dell'ultima modifica Risultato

-t specifica la data nel formato [[CC]YY]MMDDhhmm[.ss] STAMP Alcuni esempi di uso del comando:

touch miofile

Nel caso esista un file di nome ./miofile la data e l'ora di ultima modifica verranno impostate a quelle correnti. In caso contrario verr creato un nuovo file.

touch -t 0702211100 miofile Imposta come data e ora di ultima modifica del file ./miofile alle ore 11.00 del 21 febbraio 2007.

Ln Il comando ln serve a creare un collegamento (o link) ad un file o una directory. Un collegamento un file speciale che non contiene dati, ma solo un riferimento ad un altro file: ogni operazione effettuata sul collegamento viene in realt eseguita sul file a cui punta. La sintassi del comando la seguente: ln -s /percorso_file_da_collegare/file_da_collegare /percorso_del_collegamento/nome_del_collegamento L'opzione -s specifica che verr creato un collegamento simbolico.

L'uso di tale opzione consigliato. Chmod Consultare la guida ai permessi dei file.

FUNZIONI DI RICERCA
Find Il comando find serve per cercare all'interno di una directory e delle sue sottodirectory i file che soddisfano i criteri stabiliti dall'utente. La sintassi del comando la seguente: find [directory] [espressione] Alcuni esempi di usi del comando:

find . -name '*.mp3' Cerca all'interno della directory corrente ./ tutti i file con estensione .mp3.

find . -perm 664 Cerca all'interno della directory corrente tutti i file con permessi di lettura e scrittura per il proprietario e il gruppo, ma solo di lettura per gli altri utenti.

find . -name '*.tmp' -exec rm {} \; Cerca ed elimina tutti i file temporanei all'interno della directory corrente.

find /tmp -user pippo Cerca tutti i file appartenenti all'utente specificato.

Grep Consultare la relativa voce encliclopedica.

GESTIONE DEL FILESYSTEM


Mount Il comando mount serve per effettuare il montaggio di un filesystem all'interno della gerarchia di file del sistema, rendendo accessibile un filesystem a partire da una specifica directory chiamata punto di mount (o di montaggio). Alcuni esempi di uso del comando mount:

mount Visualizza i dispositivi attualmente montati, il loro punto di montaggio e il tipo di filesystem utilizzato per gestirne i dati.

mount /media/cdrom Monta in /media/cdrom il dispositivo CD-Rom.

mount -t ntfs /dev/sda1 /media/dati_windows Monta la partizione identificata come /dev/sda1 all'interno della directory /media/dati_windows, in modo che tutti i dati presenti in questa partizione diventano accessibili a partire dalla directory scelta.

Umount Il comando umount serve per smontare un dispositivo precedentemente montato. La sintassi del comando umount la seguente: umount [dispositivo] Alcuni esempi di uso del comando umount:

umount /media/cdrom Smonta il dispositivo CD-ROM.

OTTENERE INFORMAZIONI SUL SISTEMA


Du Il comando du visualizza lo spazio occupato sul disco da file o directory. La sintassi la seguente: du [opzioni] [file...] Alcune opzioni da utilizzare con il comando du: Opzione -a -s -x Risultato visualizza le informazioni sia sui file che sulle directory visualizza la dimensione totale complessiva esclude le sottodirectory che siano parte di un'altro filesystem

Alcuni esempi di uso del comando du:

du miofile Visualizza la quantit di spazio occupata da miofile.

du -s ~ Visualizza la quantit di spazio complessiva occupata dalla propria directory home.

Df Il comando df visualizza a schermo lo spazio rimasto sulle partizioni e sui dischi del proprio sistema. La sintassi del comando la seguente: df [opzioni] [file...] Alcune opzioni da utilizzare con il comando df: Opzione Risultato include nellelenco anche i filesystem con una dimensione di 0 blocchi, che sono di natura omessi. Normalmente questi filesystem sono pseudo-filesystem con scopi particolari, come le voci per l automounter. Filesystem di tipo ignore o auto, supportati da alcuni sistemi operativi, sono inclusi solo se questopzione specificata aggiunge a ciascuna dimensione un suffisso, come M per megabyte, G per gigabyte, ecc ha lo stesso effetto di -h, ma usa le unit ufficiali SI (con potenze di 1000 piuttosto che di 1024, per cui M sta per 1000000 invece di 1048576)

-a

-h -H

-t tipofs limita lelenco a filesystem del tipo specificato 10

-x tipofs limita lelenco a filesystem non del tipo specificato Un esempio di uso del comando df:

df -Ht etx3 Mostra lo spazio occupato solo dai dischi con filesystem ext3, utilizzando il suffisso specifico per l'unit di misura.

Free Il comando free mostra informazioni sulla memoria di sistema. Molto utile se si vuole rendersi conto della memoria disponibile sul sistema, della memoria attualmente in uso e di quella libera. La sintassi del comando la seguente: free [opzioni] Alcune opzioni da utilizzare con il comando free:

Opzione -b -k -t Top mostra la quantit di memoria in byte

Risultato

mostra la quantit di memoria in KiB (impostato di default) mostra una riga contente i totali

Il comando top visualizza informazioni riguardanti il proprio sistema, processi in esecuzione e risorse di sistema, utilizzo di CPU, RAM e spazio swap utilizzato e il numero di task in esecuzione. La sintassi del comando la seguente: top Per uscire dal programma, premere il tasto q. Uname Il comando uname mostra informazioni sul sistema. La sintassi la seguente: uname [opzione] Alcune opzioni da utilizzare con il comando uname: 11

Opzione -a -m -n -s -r -o mostra il tipo di macchina

Risultato visualizzer tutte le informazioni del sistema

mostra il nome host del nodo di rete della macchina mostra il nome del kernel mostra la release del kernel mostra il nome del sistema operativo

Lsb_release Il comando lsb_release mostra informazioni sulla distribuzione installata. La sintassi la seguente: lsb_release [opzione] Alcune opzioni da utilizzare con il comando lsb_release: Opzione -d -c -r -a mostra la descrizione della distribuzione mostra il nome in codice della distribuzione mostra il numero di rilascio della distribuzione mostra tutte le informazioni sulla distribuzione Risultato

12

AMMINISTRAZIONE DEGLI UTENTI

adduser: il comando adduser consente di aggiungere nuovi utenti al sistema. Esempio: sudo adduser nuovoutente

Crea un nuovo utente chiamato nuovoutente. passwd: il comando passwd consente di cambiare o impostare la propria password o la password di un utente. Esempio: sudo passwd nuovoutente Consente di impostare la password dell'utente nuovoutente. Il seguente comando invece consente di cambiare la propria password: passwd

13

ALTRI COMANDI UTILI


Cat e less I comandi cat e less servono per mostrare il contenuto di un file:

cat mostra semplicemente il contenuto del file specificato; less visualizza il contenuto di file, permette di spostarsi avanti e indietro nel testo utilizzando i tasti freccia quando i file occupano pi di una pagina di schermo. inoltre possibile eseguire delle ricerche nel testo digitando / seguito dalla parola da cercare e premendo Invio.

Per terminare il programma premere il tasto q. La sintassi del comando cat la seguente: cat nomefile La sintassi del comando less la seguente: less nomefile More Il comando more viene solitamente utilizzato in abbinamento ad altri comandi. un filtro che permette di visualizzare l'output di un comando una schermata alla volta. Alcuni esempi d'uso del comando more abbinato ad altri comandi:

ls | more cat miofile | more

Il simbolo |, solitamente chiamato pipe, serve per redirigere l'output del comando a sinistra al comando alla sua destra.

14

OTTENERE MAGGIORE AIUTO


Per ottenere maggiore aiuto o informazioni riguardo un determinato comando, esiste il comando man che serve per visualizzare il manuale di un determinato comando. La sintassi del comando man la seguente: man [comando] Ad esempio, per visualizzare la pagina di manuale dello stesso comando man sufficiente digitare il seguente comando: man man Una volta all'interno del manuale, per poter spostarsi al suo interno, basta utilizzare le frecce direzionali. Per uscire dal manuale premere il tasto q. Quasi tutti i comandi accettano anche l'opzione -h (o --help) che fornisce una breve descrizione sull'utilizzo del comando e delle sue opzioni.

15

16

ESERCIZIO 1
ESERCIZIO ESAME
Dato un disco di 100 MB gi creato e montato partizionarlo nel modo seguente: # PARTIZIONE 1 2 3 4 5 TIPO Minix Linux Fat32 Minix Linux DIMENSIONE 20 MB 20 MB 15 MB 15 MB 20 MB

SVOLGIMENTO
Creazione disco (non richiesta allesame) Avviare da windows Powershell (una shell simile a quella di UNIX) e andare nella cartella di QEMU e dare il seguente comando qemu-img.exe create nuovo.disk 100M Ora aprite con un editor di testo il file minix.bat e aggiungete dove c: qemu-system-i386.exe -L Bios -vga std -rtc base=localtime,clock=host -hda minix.qcow ^ -no-acpi -no-hpet -no-reboot -hdb nuovo.disk Per ottenere: qemu-system-i386.exe -L Bios -vga std -rtc base=localtime,clock=host -hda minix.qcow -hdb nuovo.disk ^ -no-acpi -no-hpet -no-reboot Ora facendo partire minix il nuovo disco montato su /dev/c0d1. Partizionamento Dare da minix part /dev/c0d1 Abbiamo questo men che mostra il disco (notare in alto a destra la dimensione 102312 KB = 100 MB):

17

Ci si sposta con le frecce e si cambia con il + e

Per prima cosa mettiamo la dimensione ( Nellultima colonna) Per la riga 3 (formata dalla partizione 4 e 5) lasciamo il rimanente (ovviamente deve essere maggiore stretta della la somma della 4 e 5 partizione che vogliamo creare) Assicuratevi che ci sia il valore 1 nella colonna Cyn della prima partizione, questo permette di lasciare spazio per memorizzare la tabella delle partizioni importante che sia settata prima la dimensione, rispetta al tipo in modo da non avere problemi dopo (i tipi verranno messi di default a Minix) Ottenendo questo:

18

Ora sistemiamo i tipi (sotto la colonna Type) Poich possiamo farne solo 4 allultima diamo tipo EXTENDED ottenendo ci:

Ora salviamo tutto premendo il tasto W Adesso dobbiamo pensare a creare le ultime 2 partizioni dentro quella definita extended: portiamoci su Extended e premiamo > 19

Ora rifacciamo esattamente quello che abbiamo appena fatto per le sole 2 partizioni rimanenti. Alla fine qui otterremo:

Salviamo con W E torniamo alla shell con q. Ora le partizioni create saranno indicate in minix cosi: PARTIZIONE 1 -> PARTIZIONE 2 PARTIZIONE 3 PARTIZIONE 4 -> -> -> c0d1p0 c0d1p1 c0d1p2 c0d1p3s0 c0d1p3s1

PARTIZIONE 5 ->

Creazione filesystem Da shell dare semplicemente il comando mkfs /dev/c0d1p0 per creare il filesystem alla nostra partizione 1 Per montare (e quindi usare) la partizione necessario prima creare il filesystem!

20

Montare partizione (non richiesta allesame) Dopo aver creato una cartella /dir1 e creato il filesystem per la partizione 1 mount /dev/c0d1p0 /mnt /dir1 Smontare partizione (non richiesta allesame) umount /dev/c0d1p0

21

22

ESERCIZIO 2
GUIDA SHELL SCRIPTING
Introduzione allo shell scripting
In questa guida affronteremo un argomento che, in Italia non trova, almeno a mio avviso, uno spazio adeguato costringendo troppo spesso gli sviluppatori interessati a rivolgersi a trattazioni in lingua inglese. Oggetto della nostra guida sar la pratica definita di "Shell scripting", ovvero la realizzazione di script eseguibili nella shell, pratica molto utile e diffusa nella gestione di un OS Linux. Prima di addentrarci nei meandri della programmazione ritengo opportuno avvertire che la presente guida si basa sulla cd. Bourne Shell, ovvero la shell standard (/bin/sh) dei sistemi Unix Like scritta da Steven R. Bourne (esistono altri tipi di shell, molte delle quali Bash, ksh, pdksh, zsh - compatibili con questa). L'argomento, che ha un'importanza crescente anche a seguito della grande e continua diffusione di sistemi Linux in ambito domestico ma soprattutto in ambito lavorativo, verr trattato partendo - come nostro solito - dalle basi al fine di consentire a chiunque abbia una minima conoscenza di Linux di affrontare l'argomento senza troppa fatica. Partiamo quindi dalla definizione del nostro ambito di competenza, lo Shell scripting, appunto. Lo Shell scripting consisite nella pratica di scrittura di script (file testuali contenenti un insieme organico di istruzioni) eseguibili in ambiente Shell al fine dell'esecuzione di compiti, pi o meno complessi, sulla base della combinazione dei comandi tipici offerti dal sistema operativo. Come abbiamo visto nella definizione di cui sopra, tali file sono caratterizzati dall'eseguibilit cio dal fatto di avere un particolare attributo di fruizione che consiste, appunto, nella possibilit di essere eseguito dal sistema operativo. Vi ricordo che Linux prevede, per ogni file, tre diversi attributi che possono essere diversamente combinati: r = lettura w = scrittura x = esecuzione Affinch un file sia eseguibile all'interno della shell necessario che gli venga assegnato il relativo permesso (+x) attraverso il comando chmod: chmod +x nomefile

Nella prossima lezione vedremo, passo passo, come scrivere il nostro primo script.

23

Il primo script
Vediamo ora come scrivere il nostro primo script. Effetuiamo il login nella Shell ed iniziamo a lavorare... Per prima cosa vi consiglio di creare nella Root una directory apposita dove buttare gli script (giusto per non sporcare il sistema). Quindi (supponendo di essere gi nella Root) digitiamo: mkdir miei_script ora, ovviamente, entriamoci dentro: cd miei_script Ora creiamo un file nuovo chiamato "primo.sh" (l'estensione .sh facoltativa, ma sicuramente una buona abitudine utilizzarla). Per creare il file digitiamo: touch primo.sh Ora apriamo il nostro file vuoto all'interno del nostro editor di testo preferito. Supponiamo di voler usare pico: pico primo.sh Ora riempiamo il nostro file primo.sh con il seguente contenuto: #!/bin/sh #Questo un commento e non viene interpretato echo "Lo script funziona..." Salviamo ed usciamo dall'editor. Ma cosa abbiamo scritto? Semplicissimo:

alla prima riga (#!/bin/sh) abbiamo precisato che il file deve essere processato dall'interprete sh (il percorso dovrebbe essere corretto per il 90% dei sistemi Linux, in ogni caso vi consiglio di verificare che "sh" si trovi nella directory "bin", in caso contrario correggete l'intestazione utilizzando il percorso esatto). nella seconda riga abbiamo inserito un commento, cio un'annotazione che non viene processata dall'interprete della shell nella terza riga abbiamo utilizzato il comando echo che serve per stampare a video un determinato output (nel nostro caso la frase "Lo script funziona...") che opportuno inserire tra virgolette

Ora, come abbiamo visto nell'introduzione, settiamo i permessi del file in questo modo: chmod +x primo.sh Et voil... il nostro primo script pronto per lavorare!... Non ci credete? Allora digitate: ./primo.sh E state a vedere cosa succede...

24

Le variabili
Come tutti in linguaggi di programmazione anche qui particolare attenzione deve essere rivolta all'argomento variabili. Le varibili, come sappiamo, sono dei "contenitori" (porzioni di memoria) nei quali possibile archiviare determinate informazioni (generalmente stringhe di testo o valori numerici) che possibile richiamare, modificare o elaborare all'interno del programma. In fase di assegnazione ogni variabile identificata da una denominazione univoca alla quale segue il simbolo uguale (=) che precede il valore che le viene assegnato (attenzione: non devono esserci spazi tra il nome della variabile, l'uguale ed il valore assegnato!). Facciamo subito un esempio riprendendo il file "primo.sh" che abbiamo visto nella passata lezione: #!/bin/sh MIA_VAR="Lo script funziona..." echo ${MIA_VAR} Nell'esempio qui sopra non abbiamo fatto altro che riprendere l'esempio della passata lezione semplicemente archiviando la frase di conferma all'interno della variabile MIA_VAR poi stampata da echo. Avrete notato che, nella fase di assegnazione, il simbolo uguale seguito dalla virgolette... queste, infatti, sono necessarie in quanto il valore archiviato nella variabile (nel nostro caso una frase) contiene degli spazi. Se non usassimo le virgolette la variabile MIA_VAR avrebbe come valore solamente il blocco di testo che precede il primo spazio bianco mentre il resto verrebbe ignorato. Ritengo opportuno segnalare da subito che qualora si volesse assegnare ad una variabile la risultatnte di un dato comando sar necessario sostituire le virgolette con accenti gravi(backtick). Vedi esempio: #!/bin/sh OGGI=`date +%D` echo "la data di oggi "${OGGI} Per richiamare una variabile viene utilizzato il simbolo del dollaro ($) seguito (senza spazio) dal nome della varibile stessa (preferibilmente rinchiuso tra parentesi graffa). E' opportuno segnalare che uno degli utilizzi tipici delle variabili quello di contenere valori passati real-time dall'utente. Per fare ci si usa il comando read. Facciamo un esempio: #!/bin/sh #Uso l'opzione -n per non nadare a capo echo -n "Come ti chiami?" #leggo dallo standard input il valore digitato #dall'utente e lo assegno alla variabile TUO_NOME read TUO_NOME #Stampo a video il saluto personalizzato echo "Ciao "${TUO_NOME}

25

Salvate, settate il permesso di esecuzione ed eseguite il file. Il risultato: lo script vi porr la domanda, voi rispondete... ed eccovi un bel saluto personalizato! Per finire non resta che dire che il contenuto di una variabile , per definizione, variabile... baster, infatti, effettuare una nuova assegnazione alla stessa variabile per cambiarne il contenuto. Qualora invece si voglia semplicemente svuotare una variabile del suo contenuto useremo: unset MIA_VAR che avr come effetto, appunto, lo suotamento della variabile MIA_VAR.

26

Altri tipi di variabili


Le variabili viste fino ad ora sono dette variabili locali, sono definite dal programmatore e cessano di esistere non appena termina lo script. Altro tipo di variabili sono le cd. variabili di Shell, variabili automaticamente inizializzate all'avvio della shell che permettono di riferirsi agli argomenti su linea di comando. Sono detti argomenti su linea di comando quegli argomenti passati al programma tramite, appunto, la lina di comando. Ad es.: programma argomento1 argomento 2 ... Ecco una tabellina riassuntiva di tali variabili: $# numero di argomenti su linea di comando $$? $n $0 $* $@ $$ $! opzioni fornite alla shell valore di uscita dell'ultimo comando eseguito Recupera il valore di uno specifico argomento su linea di comando, dove n varia tra 1 e 9. $1 corrisponde al primo argomento da sinistra il nome del programma corrente tutti gli argomenti su linea di comando (es. "1 2 3 4") tutti gli argomenti su linea di comando, ogniuno quotato separatamente (es. "1" "2" "3" "4") numero ID del processo corrente numero ID del processo dell'ultimo comando messo in background

Facciamo un esempio e creiamo uno script con il seguente contenuto: #!/bin/sh #Uso delle variabili di Shell echo echo echo echo echo "Numero parametri = "$# "Nome del Programma = "$0 "Tutti i Parametri = "$* "Il parmentro n.1 = "$1 "Il parmentro n.3 = "$3

Ora salviamo come "disney.sh", settiamo i consueti permessi e richiamiamo il nostro file da linea di comando seguito da quattro parametri, in questo modo: ./disney.sh pippo pluto topolino paperino L'output a video sar: Numero parametri = 4 Nome del Programma = disney.sh Tutti i Parametri = pippo pluto topolino paperino Il parmentro n.1 = pippo Il parmentro n.3 = topolino Per finire il nostro viaggio tra le variabili necessario ricordarne un'altro gruppo, le cd.variabili d'ambiente caratterizzate dal fatto di conservare nel tempo il loro valore in quanto questo pre-impostato.

27

Non ritengo opportuno soffermarmi a lungo sull'argomento per il quale mi limito a riportarvi un semplice script di esempio che utilizza alcune tra le variabili in questione: #!/bin/sh #Uso delle variabili d'ambiente echo echo echo echo echo echo echo echo echo "Informazioni sul sistema:" -e "hostname: $HOSTNAME" -e "hardware: $HOSTTYPE" -e "OS: $OSTYPE" "Informazioni sull'utente:" -e "logname: $LOGNAME" -e "homedir: $HOME" -e "shell: $SHELL" -e "path: $PATH"

Da notare che nell'esempio abbiamo utilizzato echo con l'opzione -e per abilitare l'interpretazione dei caratteri protetti con backslash. Non mi resta che concludere ricordandovi di non settare variabili locali utilizzando denominazioni riservate alle variabili d'ambiente ed alle variabili di Shell.

28

Wildcards e altri caratteri speciali


Desidero dedicare un paragrafo di questa guida ai caratteri speciali, ovvero a quei caratteri che hanno un comportamento anomalo all'interno di uno script in quanto ad essi assegnato, di default, una specifica funzione ulteriore alla loro semplice rappresentazione. Primo carattere da considerare in questa sede l'asterisco (*) anche detto wildcards. Proviamo a digitare quanto segue: echo * Ci accorgeremo subito che il risultato non sar la stampa a video del simbolo asterisco, bens l'elencazione sequenziale di tutti i file presenti nella directory. Perch? Semplice, l'asterisco (anche detto wildcards) un carattere jolly e viene interpretato dal sistema operativo come identificazione generica di un indeterminato numero di file. Se avessimo scritto: echo *.jpg Sarebbero stati stampati a video i nomi di tutti i file .jpg della directory. Se avessimo scritto: echo foto_*.jpg Sarebbero stati stampati a video i nomi di file coincidenti, ad es.: foto_mario.jpg foto_lucia.jpg foto_mary.jpg e cos via. Ma cosa fare per stampare a video l'asterisco (senza che questo venga interpretato come wildcards)? Semplice... mettiamolo tra virgolette: echo "*" Altri caratteri particolari da prendere in considerazione sono le virgolette ("), il simbolo deldollaro ($), il backslash (\) ed il backtick (`). Tutti questi caratteri, se utilizzati senza le opportune precauzioni, verranno interpretati dal sistema operativo... Perch vengano semplicemente stampati a video sar necessario e sufficiente farli precedere dal carattere di escape (una backslash). Ricapitolando: #Utilizzo errato echo "voglio stampare: " $ \ `" #Utilizzo corretto echo "voglio stampare: \" \$ \\ \`" Solo nel secondo caso i nostri simboli speciali saranno stampati a video correttamente...

29

Operatori
In questo paragrafo passiamo in rasegna i cd. operatori suddividendoli in gruppi Operatori Matematici Si utilizzano solo ed esclusivamente con valori numerici + Somma Sottrazione

\* Moltiplicazione / Divisione

** Esponenzia il primo numero al secondo % Ritorna il resto di una divisione Per effettuare operazioni matematiche sulle variabili necessario utilizzare alternativamente:

il comando esterno expr tra apici gravi le doppie parentesi tonde (( e )) il costrutto let

Vediamo qualche esempio: #!/bin/sh #Operazioni matematiche con numeri interi #Definiamo due variabili numeriche X=10 Y=4 #Uso di expr tra apici gravi R1=`expr $X - $Y` #Uso le doppie parentesi R2=$((X-Y)) #Uso di let let "R3 = X - Y" #Stampiamo a video i risultati echo "risultato di expr: "$R1 echo "risultato delle dopie parentesi: "$R2 echo "risultato di let: "$R3 Ritengo opportuno ricordare che la funzione dei backtick, come gi detto, quella di circoscrivere (come fanno le virgolete nel caso di variabili stringa conteneti spazi vuoti) operazioni composte da comandi seguiti da uno o pi attributi tra loro separati (come nel caso di expr visto sopra). Da ricordare che expr funziona solo con i numeri interi. Se volete lavorare con numeri decimali utilizzate il comando bc (binary calculator) in questo modo:

30

echo "2.11 + 8.7" | bc Riprendiamo lo script matematico visto sopra ponendo che le due variabili X e Y siano numeri decimali: #!/bin/sh #Operazioni matematiche con numeri decimali X=7.3 Y=4.22 Z=`echo "$X + $Y" | bc` echo $Z Operatori di Confronto (Numerico) Si utilizzano solo ed esclusivamente con valori numerici -eq Equivalenza -ne Disuguaglianza -gt Maggiore -ge Maggiore o Uguale -lt -le Minore Minore o Uguale

Operatori di Confronto (Stringhe) Si utilizzano solo ed esclusivamente con variabili stringa -n Verifica che la stringa sia di lunghezza maggiore di zero -z Verifica che la stringa abbia lunghezza zero = Verifica che due stringhe siano uguali

!= Verifica che due stringhe siano diverse < > Verifica che la prima stringa sia lessicograficamente minore della seconda Verifica che la prima stringa sia lessicograficamente maggiore della seconda

Operatori Logici ! Operatore di negazione, inverte il valore logico dell'espressione al quale viene applicato. !(vero) = falso

-a Operatore AND. Ritorna vero se entrambi gli argomenti passati lo sono. -o Operatore OR. Ritorna vero se almeno uno degli argomenti lo . Uno degli utilizzi tipici degli operatori (di confronto e tipici) quello di partecipare alla costruzione di condizioni, che assumono un particolare rilievo, come vedremo, nelle istruzioni di controllo. E' opportuno dar menzione in questa sede che esistono altri operatori, ma ai fini di questa guida preferisco limtarmi a quelli sopra menzionati.

31

Istruzioni di controllo: IF
le istruzioni di controllo sono, come dice gi il loro nome, un insieme di istruzioni che controllano (appunto) il funzionamento del programma sulla base del verificarsi o meno di date condizioni. Per prima cosa vediamo il funzionamento del costrutto if. Partiamo da un esempio: poniamo di voler porre una domanda e di stampare a video un messaggio a seconda che la risposta sia corretta o meno: #!/bin/sh #Faccio la mia domanda echo -n "Qual' il nome di Garibaldi? " #Recupero la risposta read RISPOSTA #Stampo a video il risultato if [ ${RISPOSTA} = "giuseppe" ] then echo "Risposta esatta" else echo "Risposta sbagliata" fi Il costrutto if ha una sintassi molto semplice: si esprime la condizione tra parentesi quadre e se essa risulta vera la shell esegue le istruzioni subito dopo then. In caso contrario possibile specificare delle istruzioni opzionali alternative subito dopo else. Ogni costrutto if termina con fi. Da notare che dopo la parentesi siamo andati a capo... ma avremmo anche potuto scrivere cos: if [ condizione ]; then Invece di andare a capo, quindi, si aggiunge un punto e virgola alla chiusura della parenresi quadra. Il punto e virgola ha infatti la funzione di separatore di comandi che quindi possono essere cos mesi silla stessa riga. Nel caso in cui ci siano condizioni multiple possibile usare elif al posto dei vari if ed esprimere una sola volta le istruzioni alterntative con else alla fine. Facciamo un altro esempio: #!/bin/sh #Faccio la mia domanda echo -n "Quanti anni hai? " #Recupero la risposta read ANNI #Stampo a video il risultato if [ ${ANNI} -lt 10 ] then

32

echo "Sei un bambino" elif [ ${ANNI} -lt 18 ] echo "Sei minorenne" else echo "Sei maggiorenne" fi Non mi resta che darvi appuntamento al prossimo paragrafo dove vedremo una valida alternativa ad if...

33

Istruzioni di controllo: CASE


Una valida alternativa ad if offerta dal costrutto case. Con case, nella sostanza, si costruisce una casistica di evenienze ad ognuna delle qiuali associata una data risposta del programma. Vediamo subito un esempio e riprendiamo il primo visto nel passato paragrafo rivisto e corretto con l'utilizzo di case: #!/bin/sh #Faccio la mia domanda echo -n "Qual' il nome di Garibaldi? " #Recupero la risposta read RISPOSTA #Costruisco una casistica di risposte case $RISPOSTA in garibaldi) echo "Risposta esatta" ;; *) echo "Risposta sbagliata" ;; esac Ogni istruzione case richiede - almeno - un pattern (nel nostro esempio lo la variabile RISPOSTA). Successivamente vanno specificati i singoli valori possibili del pattern seguiti dal simbolo ), dalle relative istruzioni e infine da una coppia di punto e virgola. Il simbolo asterisco (*) esprime tutti i valori non specificati ed opzionale. Ogni costrutto case termina con esac.

34

I cicli for e while


Un ciclo una ripetizione di una determinata azione per un dato numero di volte sulla base di un dato delimitatore. Per realizzare un ciclo in ambiente di shell scripting si usa for oppure while. Vediamoli entrambi. Il ciclo FOR crea un iterazione sulla base di una data lista di valori o di una data condizione. Esempio di lista di valori: #!/bin/sh for X in 1 2 3 4 5 do echo $X done In questo caso il ciclo for si ripete per ogni valore specificato (nel nostro caso verranno stampati i numeri da 1 a 5, ma avremmo potuto usare anche valori non sequenziali oppure non numerici). Altro modo di utilizzare for il seguente: #!/bin/sh for (( X=0; X<10; X++ )) do echo $X done Nell'esempio qui sopra for viene utilizzato definendo, da sinistra a destra:

valore di partenza condizione limite. Il ciclo prosegue fino a quando questa condizione risulta vera incremento (X++ aggiunge 1 al suo precedente valore numerico)

Altro modo di creare iterazioni all'interno dei nostri script l'utilizzo di WHILE. Grazie a while si ripetono determinate azioni fino a quando la condizione limite risulta soddisfatta. #!/bin/sh X=0 while [$X -le 5] do echo $X X=`expr $X + 1` done Nel nostro caso il ciclo continer fino a quando la condizione limite (X minore o uguale a 5) risulta vera.

35

Scrivere una funzione


Anche lo shell scripting prevede la possibilit di scrivere delle funzioni. Una funzione una porzione di codice indipendente alla quale viene assegnata, appunto, una specifica funzione all'interno del programma. Scrivere funzioni molto utile quando si deve compire una determinata operazione complessa pi di una volta all'interno dello stesso programma o della stessa suite di programmi. Grazie alle funzioni si evita, infatti, di riscrivere pi volte il medesimo codice operativo ma ci si limita a richiamare la funzione alla quale stato adibito quello specifico compito. Una funzione pu essere scritta all'interno dello script oppure su un file separato da includersi nello o negli script che usufruiranno della funzione. Vediamo nell'esempio una semplice funzione scritta su un apposito file (separato dallo script principale) che chiameremo "miafunzione.lib": #Attenzione!!! #Non va messo #!/bin/sh #Funzione per il calcolo del prezzo di una merce #compreso di IVA. #La funzione prevede, quale unico parametro, il #prezzo al netto dell'iva. tot_iva() { IVA=`expr $1 / 100` IVA=`expr $IVA \* 20` TOT=`expr $1 + $IVA` echo $TOT } Come abbiamo visto la sintassi data dal nome della funzione seguita da () e da una coppia di parentesi graffe al cuni interno viene inserito il codice operativo. Ora vediamo il contenuto dello script principale che richiama il file "miafunzione.lib" per poterne sfruttare le potenzialit: #!/bin/sh #Includo il file miafunzione.lib #Nel nostro es. il file si trova nella stessa directory . ./miafunzione.lib #Definisco due variabili contenenti il prezzo #netto (senza IVA) di due ipotetici prodotti VHS=10 DVD=20 #Richiamo la funzione per calcolare il prezzo compreso IVA echo "Prezzo di una VHS compreso Iva: `tot_iva $VHS` Euro" echo "Prezzo di un DVD compreso Iva: `tot_iva $DVD` Euro"

36

Come risulta intuitivo non sar necessario scrivere pi volte il codice per il calcolo del prezzo totale... baster scriverlo una volta nella funzione e poi richiamare quest'ultima quante volte la si necessita.

37

Conclusioni
Sulla base di quanto sin qui esposto dovreste essere gi in grado di scrivere dei (pi o meno) semplici script per la Shell che vi aiuteranno nella gestione del vostro OS Linux permettendovi di creare, ad esempio, comandi complessi in grado di svolgere funzioni originariamente non previste dal sistema operativo. Ad esempio potreste programmare uno script per la pulizia dei file di log pi vecchi, oppure ancora uno script per il backup e compressione dei vostri dati, ancora uno script per automatizzare il trasfrimento via FTP di determinati file, uno script di diagnostica dell'intero sistema, ecc. Come avrete capito le possibilit che vi si presentano sono decisamente parecchie... Non vi resta che applicarvi e fare un piccolo sforzo di fantasia per combinare le nozioni che avete appreso in questa semplice guida con la comune conoscenza di Linux e dei sui comandi di cui trovate (per i prncipali di questi) ampia e circostanziata documentazione sulla nostra Guida a Linux. Con un pizzico di impegno vi accorgerete che potrete creare cosine davvero interessanti. Buon lavoro!

38

ESERCIZI TIPICI
Specificare l'occupazione totale di un utente in un sistema (somma delle dimensioni dei suoi file...) #!/bin/sh if [ $# -ne 1 ]; then echo "syntax: user_size <user_name>" exit 1 fi ID="$(grep "^$1" /etc/passwd | cut -f 3 -d :)" if [ "$ID" = "" ]; then echo "User \"${1}\" not found" exit 1 fi echo "calculating..." SUM=0 for ITEM in $(find / -user "$ID" -type f | xargs du | cut -f 1); do SUM=$(expr ${SUM} + ${ITEM}) done echo "User \"${1}\" takes ${SUM} KB into the system" exit 0

Per ogni utente del sistema specificare qual il suo file di dimensioni maggiori #!/bin/sh # Per ogni utente trovare il suo file di dimensione maggiore for UID in $(cut /etc/passwd -d : -f 3 | sort -n | uniq); do FILE=$(find / -type f -user $UID | xargs du | sort -nr | head -1) if [ "$FILE" != "" ]; then DIM=$(echo "$FILE" | cut -f 1) NOME=$(echo "$FILE" | cut -f 2) echo "UID: $UID => File: $NOME ($DIM KB)" else echo "UID: $UID => Nessun file trovato" fi done

Trovare il file pi "grosso" sul sistema find / -type f | xargs du | sort -nr | head -1 find / -type f | xargs du | sort -n | tail -1

Archiviare i files pi grandi di 5k e pi piccoli di 100k? find / -type f -size +10 -a -size -200 | xargs tar cvf archivio.tar 39

Copiare i file da una directory all'altra senza cambiare i permessi: cp /directory/albero1/* /directory/albero2

Spostare tutti i files che iniziano per m da una directory (e sottodirectory) ad un'altra mv /directory/albero1/m* /directory/albero2

Trovare tutti i files eseguibili > 5k e evidenziando i 5 pi grandi find / -type f -size +10 | xargs ls -lF | grep "\*$" | tr -s ' ' ' ' | cut -d ' ' -f 5,9 | sort -n | tail -5

Archiviare i files modificati nell'ultima settimana find / -type f -mtime -7 | xargs tar cvf archivio.tar

Trovare il processo che occcupa pi memoria ram ps -axl | sort +7 -nr | head -1 | tr -s ' ' ' ' | cut -d ' ' -f 8,12

Trovare i tre files pi grossi per ogni utente #!/bin/sh for UID in $(cut /etc/passwd -d : -f 3 | sort -n | uniq); do echo "Utente $UID:" find / -type f -user $UID | xargs du | sort -nr | head -3 done #/usr/bin/sh cut -f 1 -d : /etc/passwd |while read user do file=$(find / -type f -user $user |xargs du |sort -nr |head -1|cut -f 2) dimensione=$(find / -type f -user $user |xargs du |sort -nr |head -1|cut -f 1) if [ "$file" != "" ];then echo "il file " $file " di dimensione "$dimensione " e'il piu' grosso per l'utente "$user else echo "l' utente " $user "non ha file" fi 40

done

Archiviare tutti i files che contengono la parola "login" find / -type f | xargs grep -l "login" | xargs tar -cvf archivio.tar

Trovare tutti i file che includono la parola "login" ed archiviarli su di un file .txt find / -type f | xargs grep -l "login" >> list.txt

Cercare tutti i file con SUID attivato find / -type f -perm -004000 (testato)

Archiviare i files pi piccoli di 100KB ma pi grandi di 5KB: find / -type f -size +10 -a -size -200 | xargs ar rc archive.a Opzioni: r => sostituisci o aggiungi (nel caso un file non sia gi presente) c => crea l'archivio (sopprime il noioso messaggio di notifica, non fa nulla se l'archivio esiste gi) t => visualizza il contenuto (ar t archive.a)

Trovare tutti i processi per ogni utente e fornirne l'occupazione in memoria??? #!/bin/sh SUM=0 for UID in $(cat /etc/passwd | cut -d : -f 3); do for PROCSIZE in $(ps alx | tr -s ' ' ' ' | cut -d ' ' -f 4,8 | grep "^$UID" | cut -d ' ' -f 2); do SUM=$(expr $SUM + $PROCSIZE) done echo "Utente $UID : $SUM KB di processi in memoria" SUM=0 done ps alx => stampa tutti i processi in formato lungo tr -s ' ' ' ' => comprimo tutti gli spazi contigui in un solo spazio (fondamentale, altrimenti non funziona il cut)

41

cut -d ' ' -f 4,8 => estrai la 4^ e l'8^ colonna (che dopo tr sono separate da un solo spazio) che sono l'UID del proprietario e la dimensione (le ho trovate osservando il comportamento dei comandi precedenti, non c' un manuale su come farlo!) grep "^$UID" => cerca l'UID interessato a partire dall'inizio della riga (potrebbe confondersi con la dimensione di un processo) Ricordo che le colonne ora avranno il formato "0 689" ovvero UID + spazio + SIZE cut -d ' ' -f 2=> Una volta ristretto il campo dell'utente estraggo la sola colonna dei SIZE per poi sommarli tutti

Trovare il processo con pid dispari che occupa pi spazio in memoria? #!/bin/sh MAXSIZE=0 MAXPID=0 for PROC in $(ps alx | tr -s ' ' : | cut -d : -f 5,8); do PID=$(echo $PROC | cut -d : -f 1) SIZE=$(echo $PROC | cut -d : -f 2) if [ $PID % 2 -eq 1 -a $SIZE -gt $MAXSIZE ]; then MAXPID=$PID MAXSIZE=$SIZE fi done echo "Processo con PID dispari pi esoso: $MAXPID con $MAXSIZE KB" Spiegazione: Dalla lista di tutti i processi comprimo tutti gli spazi contigui nel carattere ':' che user come separatore di colonne (lo spazio faceva danno); estraggo le colonne 5 e 8 che sono PID e SIZE anche qui trovate osservando il comportamento dei comandi) Le righe ora sono della forma PID:SIZE (12:552) Estraggo i PID come prima colonna dalla variabile PROC Estraggo i SIZE come seconda colonna dalla variabile PROC Se il PID % 2 uguale a 1 (dispari) e SIZE maggiore di MAXSIZE Aggiorno il PID e il SIZE massimi

Calcolare la somma della dimensione di file eseguibili che hanno all'interno la parola copyright non sensitive #! /bin/sh SUM=0 for SIZEFILE in $(find / -type f | xargs grep -il "copyright" | xargs ls -lF | grep "\*$" | tr -s " " : | cut -d : -f 5); do SUM=$(expr $SUM + $SIZEFILE) done 42

echo "la somma : $SUM" le opzioni -il del grep mi consentono di: -i per il case insensitive -l per elencare il nome del file contente la parola copyright (altrimenti mi avrebbe stampato per ogni file la riga contenente la parola copyright)

Trova il processo che occupa per ogni utente pi memoria #! /bin/sh MAXSIZE=0 for USER in $(cat /etc/passwd | cut -d : -f 3 | uniq); do for PROC in $(ps -axl | tr -s " " : | cut -d : -f 4,8 | grep -v "SZ"); do UID=$(echo $PROC | cut -d : -f 1) SIZE=$(echo $PROC | cut -d : -f 2) if [ $UID -eq $USER -a $SIZE -gt $MAXSIZE ]; then MAXPROC=$PROC MAXSIZE=$SIZE fi done echo "il processo dell'utente $USER + grande : $MAXPROC" MAXPROC="nessun processo" MAXSIZE=0 done

Copiare una directory mantenendo la struttura delle sottodirectory e i permessi, evitando per di copiare il contenuto delle cartelle(i file che all'interno che non sono directory) #/bin/sh cpdir -p /directoryA /directoryB for file in $(find /directoryB -type f); do rm $file done oppure #! /bin/sh cpdir -pr /bin /bin2 rm $(find /bin2 -type f)

43

Quali e quante estensioni ci sono nel sistema? (per estensioni si intende qualsiasi cosa ci sia dopo il carattere ., es: archivio.gz) La soluzione questa: find / | rev | cut -f 1 -d '.' | grep -v / | rev | sort | uniq -c | sort -n Spiegazione: find / trova tutto (files e directories) a partire dalla root dir rev inverte ogni riga dell'output cut -f 1 -d '.' estrae il primo campo di ogni riga usando il . come separatore grep -v / eliminazione delle sole directories rev inverte di nuovo ogni riga dell'output sort ordina l'output uniq -c elimina righe duplicate contandole, ora l'output del tipo 123 gz sort -n (non necessario) ordina i risultati numericamente Nota: Si pu evitare il grep -v / usando cut -f 1 -d '.' -s. Okkio che cos trovi anche tutte le cartelle e file nascosti ( del tipo .cartella o .file). Ho fatto uno script simile al tuo, escludendo cartelle e file nascosti: find / -type f -name *.* | tr -s '/' ' ' | rev | cut -d ' ' -f 1 | rev | grep -v "^\." | rev | cut -d '.' -f 1 -s | rev | sort | uniq -c find / -type f -name *.* cerco tutti i file che contengono un punto nel nome del file (i file trovati sono completi di path ad es. /root/prova/file) tr -s '/' ' ' spazi al posto di / rev stampo il nome del file al contrario cut -d ' ' -f 1 estraggo il primo campo ( il nome del file al contrario). In questo modo ho il nome del file senza path rev ristampo il nome del file "dritto" grep -v "^\." escludo tutti i file che INIZIANO con un punto (sono quelli nascosti) rev non lo ripeto pi cut -d '.' -f 1 -s estraggo il primo campo. Cos ho l'estensione del file rev sort ordino le estensioni in ordine alfabetico, cos posso eliminare le ripetizioni con uniq uniq -c per ogni estensione ho il numero di ripetizioni

Qualcuno sa cosa significa fare la statistica dei file < 10k 100k 1000k ?????????? #! /bin/sh TOT=$(find / -type f | wc -l | tr -s ' ' : | cut -f 2 -d :) DIECIK=$(find / -type f -size -20 | wc -l | tr -s ' ' : | cut -f 2 -d :) CENTOK=$(find / -type f -size -200 | wc -l | tr -s ' ' : | cut -f 2 -d :) MILLEK=$(find / -type f -size -2000 | wc -l | tr -s ' ' : | cut -f 2 -d :) 44

CENTO=100 STAT=$(expr $DIECIK \* $CENTO) STAT1=$(expr $STAT / $TOT) STAT=$(expr $CENTOK \* $CENTO) STAT2=$(expr $STAT / $TOT) STAT=$(expr $MILLEK \* $CENTO) STAT3=$(expr $STAT / $TOT) echo "I file inferiori a 10k sono il ${STAT1}%" echo "I file inferiori a 100k sono il ${STAT2}%" echo "I file inferiori a 1000k sono il ${STAT3}%"

Per trovare ogni singolo file di testo che contiene la parola "copyright" basta fare: find / -type f | xargs grep -l "copyright" | grep "\.txt$"

Somma delle dimensione di tutti i file di solo testo (non eseguibili) che contengono al loro interno la parola copyright #!/bin/sh SOMMA=0 for VAR in $(find / -type f | xargs grep -l "copyright" | grep "\.txt$" | xargs du | cut -f 1); do SOMMA=$(expr $VAR + $SOMMA) done echo $SOMMA

per cercare un eseguibile (per stato detto pi volte) fai cos find / -type f | xargs ls -lF | tr -s ' ' ' ' | cut -d ' ' -f 5,9 | grep "\*$"

dove ls -F mette in fondo al nome del file alcuni simboli... mette un * se eseguibile qunidi con tr ' ' ' ' comprimo tutti gli spazi con cut, con delimitatore lo spazio (-d ' ') selezioni i csmapi 5 e 9 (PID e SIZE) e poi estraggo le linee che hanno * alla fine (devo mette \ davanti a * per farlo interpretare bene... e il $ significa "cerca in fondo alla riga"

Trovare tutte le dir che abbiano meno di 5 sottodirs: #!/bin/sh echo "Script per stampare le dir che hanno meno di 5 sottodir"; 45

for dir in $(find / -type d); do ls -F -1 $dir | grep '/' | wc -w > a.tmp if [ $(cat a.tmp) -lt 6 ]; then echo $dir; cat a.tmp; else echo ''; fi; rm a.tmp; done;

Trovare il file pi grande di tipo testo che abbia un numero di righe pari sizef=0 for file in $(find / -type f -name '*.txt'); do nrrighe=$(wc -l $file | tr -d ' ' | cut -f 1 -d /) size=$(du $file | cut -f 1) if $(expr $(expr $nrrighe % 2) -eq 0 ); then if $(expr $size -gt $sizef); then sizef=$size filef=$file fi fi done echo "Il file di testo pi grande con numero di righe pari : echo $filef

Calcolare per ogni utente il numero di file modificati nell'ultimo mese for user in $(cut /etc/passwd -d : -f 3 | sort -n | uniq); do item=$(find / -type f -user $user -mtime -31 | wc -l | tr -d ' ' | cut -f 1) echo "L'utente $user ha modificato $item file nell'ultimo mese" done

Per ogni utente del sistema stampare i gruppi a cui appartiene, senza utilizzare i comandi id e groups. for x in $(cat /etc/passwd |cut -d ':' -f 1); do echo "$x: ""$(for y in $(cat /etc/group|grep -s $(cat /etc/passwd|grep -s "$x"|cut -d ':' -f 3)|cut -d ':' -f 1); do echo -n "$y ";done)"; 46

done

Trovare tutti gli script del sistema, minori di 1 k, copiarli su /tmp/script/ Aggiungerli tutti i file su un file.tar ! #!/bin/sh mkdir script; FILE=$(find / type -f -size +2 | xargs grep -l "#!/bin/sh" | cp * /tmp/script);

Trovare tutti i file modificati di venerd #!/bin/sh find / -type f |while read line do giorno=$(stat -Mtime $line |awk '{$1 print $1}') if [ "$giorno" = "Fri" ]; then ls -l $line fi done

Memorizzare in un archivio .ar tutti i file creati negli ultimi 2 giorni di dimensione minore di 5k. find / -type f -size -10 -ctime -2 |xargs ar rc filearc.ar

Calcolare per ogni utente il numero di file modificati nell'ultimo mese cut -f 1 -d : /etc/passwd |while read line do conta=$(find / -type f -mtime -30 -user $line|xargs ls -l|wc -l) echo "lo user " $line "ha modificato " $conta "file negli ultimi 30 giorni " done

Calcolare la dimensione totale di tutti i file .c #/usr/bin/sh 47

find / -type f -name *.c | while read line do conta=$(stat -size $line) tot=$(expr $conta + $tot) echo $tot > totale done

Memorizzare in un archivio .ar tutti i file creati negli ultimi 2 giorni di dimensione minore di 5k. find / -type f -size -10 -ctime -2 |xargs ar rc filearc.ar

Per ogni utente trovare i 3 file pi vecchi del sistema.. #!\bin\sh USERS=$(cut -d : -f 1 | sort -f | uniq); for us in $USERS; do FILE=$(find / -type f -user $us | xargs ls -ltsT | tail -3); echo "FILE UTENTE: $us; echo $FILE; done

Calcolare il numero di righe totali che ha scritto sul filesystem un certo utente nell'ultimo mese find / -mtime -30 |while read line ; do; awk '{ if ($(ls -l $linea)) $3 == 'root' print }'; done; find / -mtime -30 |while read line ; do; ls -l $line | awk '{ print $3": "$9}' | grep ^root done;

Calcolare la somma delle dimensioni dei file *.s. #/usr/bin/sh

find / -name *.s | while read line; 48

do; sum=$(ls -l $line| awk '{print $5}'); #### pippo= $(ls -l $line| awk '{sum = sum + $5} END {print sum}' ###echo $sum; tot=$(expr $sum + $tot); echo $tot > tmp; done;

Trovare tutti i file che hanno il numero di blocchi pari #/usr/bin/sh ###sum=0; find / |while read line; do; ls -l $line| awk '{if ($5%2==0) print }'; done;

Trovare i file pi vecchi di un mese find / -mtime -30 |while read line ; do; awk '{ if ($(ls -l $linea)) $3 == 'root' print }'; done;

Mostrare, per ogni utente, il numero di file presenti sul sistema. find / -f |xargs wc -l -Calcolare il numero di righe totali che ha scritto sul filesystem un certo utente nell'ultimo mese

Stampare i file che finiscono per c con un numero di caratteri dispari e visualizzare la loro data #/usr/bin/sh find / -name *.c |while read line ; do; wc -c $line|awk '{if ($1%2 != 0 ) ls $2 print $2}'|xargs ls -l; done;

49

Trovare tutti i file col numero dispari di righe (quindi sono i file di testo) find / -f|while read line ; do wc -l $line| awk '{if (($1%2) !=0) print $line}' ;done;

Trovare tutti i file modificati di venerdi' (sia un venerdi' particolare che di venerdi' in generale) #/usr/bin/ksh find / -type f|while read line; do ; stat $line |awk '{if ($1 =="Mtime:" && $2 =="Fri") print "'${line}'" }' ; done;

Trovare tutti i link simbolici presenti nel sistema. find / | while read line;do if test -h $line; then echo $line ok; fi; done

Trovare tutti i file col numero dispari di righe (quindi sono i file di testo) find / -f|while read line ; do wc -l $line| awk '{if (($1%2) !=0) print $line}' ;done;

Trovare gli utenti ed i gruppi distinti proprietari dei file nelle directory /bin, /sbin, /usr/bin e /usr/sbin. Riportare i comandi utilizzati. ls -l /bin /sbin /usr/bin /usr/sbin |awk '{print $3, $4}'|sort |uniq

50

ESERCIZIO 3
Arrivato a questo punto se hai fatto bene i primi 2 hai gi 24/30. Per far questo esercizio bisogna aver capito bene come funziona il kernel minix. Questo significa che bisogna smanettare allinterno del kernel e provare da soli

CONSIGLI
Le dritte che vi posso dare sono:

provate a farlo e fate vedere al professore che sapete muovermi allinterno del kernel: o cercate almeno di trovare il file che si deve modificare, magari anche la riga di codice (se poi non si ha la pallida idea di cosa sostituire cmq meglio di non aver fatto nulla) o a volte un find e/o un grep vi pu far trovare il file e la riga! o La maggior parte delle volte i file da modificare sono nei percorsi: /usr/src/servers/pm /usr/src/servers/fs

ESERCIZI TIPICI
Stampare "MUOIO!" ogni volta che un processo termina kprintf ("MUOIO!\n"); Nei file: /usr/src/kernel/system/do_exit.c /usr/src/kernel/system/do_kill.c nelle funzioni con il rispettivo nome [do_exit() e do_kill()] C'era una postilla ovvero di far stampare ance il PID del processo. Era un problema perch all'interno del kernel il proc_nr non il PID della tabella dei processi di PM ma il numero del processo della tabella del Kernel che non sono lo stesso numero quindi pescare quello giusto era comlicato e l'ora si faceva tarda... quindi il prof mi ha detto che se non lo facevo non era importante e non mi ha penalizzato. (ma questo rimanga tra me e voi...) In /usr/src/tools/ make clean (per sicurezza ripartiamo da zero) make image make hdboot (credo sostituisca anche make image, provate...) Ci sono poi due casi particolari Modifica delle librerie: prima di make hdboot inserite anche make libraries (mooolto lento) Esercizio Tasto F8 (vedi thread apposito): sempre prima di make hdboot scrivete make services Il tuo problema sai che forse nel reboot?! 51

Prova a fare un bel shutdown e al riavvio quando sei al boot loader non fare nessuna scelta, lascia che il sistema parta dopo pochi secondi [A questo proposito me ne sono successe di tutte come a te...]

Modifica al kernel richiesta: impedire che vengano creati file il cui nome cominci con la lettera m. Intervento individuato: nei sorgenti del pm, nel file open.c c' una funzione do_creat() Uno dei parametri sembra essere il nome. Basterebbe quindi inserire un if alla inizio della funzione che controlla il nome e se quest'ultimo comincia con m, terminare con errore. In realt il Prof. Monga ha detto che quello non proprio il nome del file ma una stringa che lo rappresenta (una specie di codifica interna di Minix). Ma la risposta andava bene ugualmente. Ricordo che la tua domanda stata fatta a lezione... Il nome di un file lo si trovava passando per: /usr/src/servers/fs/open.c -> do_creat() -> common_open() -> new_node() In questa funzione nella variabile string c' il nome del file e basta aggiungere dopo la riga: *ldirp = parse_path(path, string, opaque ? LAST_DIR : LAST_DIR_EATSYM); Il seguente pezzo di codice:

code:-------------------------------------------------------------------------------if (*string == 'M' || *string == 'm') { printf ("Niente nomi che iniziano con emme!!!\n"); return (NIL_INODE); }

Kernel: Stampare il messaggio quando un processo termina Sufficiente che la printf sia all'interno della procedura pm_exit() ovviamente nei sorgenti del PM) che viene chiamata in qualsiasi caso: syscall exit() oppure SIGKILL o SIGTERM NOTA: ho notato con un amico che qemu tende a crashare se il messaggio della exit non termina con un newline, quindi vi conviene che il messaggio sia sempre qualcosa del tipo printf("\nMESSAGGIO\n"); che per inciso produce anche un output pi leggibile (per quanto possa interessare leggere "MESSAGGIO" mille volte)

Kernel: Stampare un messaggio quando un processo viene killato Modificare i seguenti file: 52

usr/src/servers/pm/forkexit.c oppure se non si conosce il file: cd /usr/src/servers/pm grep pm_exit * 1)io vado in /usr/src/servers/pm/ 2)forkexit.c 3) mi porto alla fine della funzione pm_exit() 4) metto il printf 5) vado in /usr/src/tools/ 6) eseguo i comandi make clean, make image, make hdboot 7) shutdown

Kernel: cambiare la politica di allocazione della memoria in best fit Indovinato: si deve cambiare il file /usr/src/servers/pm/alloc.c pi esattamente la funzione alloc_mem dove viene usato la politica firts fit.

Kernel: Ogni volta che viene cancellato un file che inizi per 'x' stampare un messaggio inserire in /usr/src/servers/fs/link.c NELLA PROCEDURA UNLINK_FILE

if (file_name[0] == 'x') printf ("File rimosso");

Kernel: scrivere un messaggio sullo schermo quando viene avviato un programma setuid root

for file in $(find / -type f -name *.s); do sum=$(stat -size $file) tot=$(expr $sum + $tot) echo $tot done

53

54

Guida comandi Unix/Linux

.com

Informazioni di sistema date mostra la data e l'ora correnti cal mostra il calendario del mese corrente uptime da quanto tempo la macchina in funzione w mostra gli utenti collegati whoami mostra l'utente con cui si collegati finger user mostra informazioni su user uname -a mostra le informazioni sul kernel cat /proc/cpuinfo informazioni sulla CPU cat /proc/meminfo informazioni sulla memoria man command manuale per il comando command df mostra informazioni sui dischi du informazioni sull'utilizzo dello spazio disco free informazioni sulla memoria libera e sullo spazio di scambio whereis app mostra possibili locazioni di app which app mostra quale app viene normalmente eseguita Compressione tar cf file.tar files crea un archivio tar con nome file.tar contenente files tar xf file.tar estrai il contenuto dell'archivio file.tar tar czf file.tar.gz files crea un archivio tar compresso con Gzip tar xzf file.tar.gz estrai un archivio tar decomprimendolo prima con Gzip tar cjf file.tar.bz2 crea un archivio tar compresso con Bzip2 tar xjf file.tar.bz2 estrai un archivio tar decomprimendolo prima con Bzip2 gzip file comprime file e lo rinomina in file.gz gzip -d file.gz decomprime file.gz in file Rete ping host effettua un ping di host e mostra il risultato whois domain recupera le informazioni whois per il dominio domain dig domain recupera le informazioni DNS per il dominio domain dig -x host effettua un reverse lookup di host wget file scarica file wget -c file prosegue un download interrotto Installazione Installazione da sorgente: ./configure make make install dpkg -i pkg.deb installa un pacchetto (Debian) rpm -Uvh pkg.rpm installa un pacchetto (RPM) Scorciatoie Ctrl+C interrompe il comando corrente Ctrl+Z ferma il comando corrente, da continuare con fg in primo piano o in sottofondo con bg Ctrl+D esci dalla sessione corrente, simile a exit Ctrl+W cancella una parola nella linea corrente Ctrl+U cancella l'intera linea Ctrl+R cicla attraverso la lista dei comandi recenti !! - ripete l'ultimo comando exit esci dalla sessione corrente * utilizzare con estrema cautela.

Comandi sui file ls elenco contenuto directory ls -al elenco formattato con file nascosti cd dir cambia directory di lavoro a dir cd cambia directory di lavoro a directory home pwd mostra directory di lavoro corrente mkdir dir crea directory dir rm file cancella file file rm -r dir cancella directory dir rm -f file forza cancellazione di file rm -rf dir forza cancellazione directory dir * cp file1 file2 copia da file1 a file2 cp -r dir1 dir2 copia dir1 a dir2; crea dir2 se non esiste mv file1 file2 rinomina o sposta file1 in file2 se file2 una directory esistente, sposta file1 nella directory file2 ln -s file link crea collegamento simbolico link al file file touch file crea o modifica file cat > file redireziona lo standard input in file more file mostra il contenuto di file head file mostra le prime 10 linee di file tail file mostra le ultime 10 linee di file tail -f file mostra il contenuto di file mentre viene aggiornato iniziando dalle ultime 10 linee Gestione processi ps mostra i processi attivi top mostra interattivamente tutti processi attivi kill pid uccide il processo con id pid killall proc uccide tutti i processi con nome proc * bg elenca i job fermati o in sottofondo; ripristina un job fermato e messo in sottofondo fg porta il job pi recente in primo piano fg n porta il job n in primo piano Permessi file chmod octal file cambia i permessi di file a octal, numero di 3 cifre, rispettivamente per l'utente, il gruppo e tutti gli altri, somme di: 4 lettura (r) 2 scrittura (w) 1 esecuzione o visita (x) Esempi: chmod 777 lettura, scrittura ed esecuzione per tutti chmod 755 rwx per il proprietario, rx per il gruppo e tutti gli altri Per ulteriori dettagli si esegua man chmod. SSH ssh user@host connessione a host come user ssh -p port user@host connessione a host sulla porta port come user ssh-copy-id user@host aggiunge la propria chiave ad host per l'utente user per permettere un accesso pre-autenticato o senza password Ricerca grep pattern files cerca pattern in files grep -r pattern dir cerca ricorsivamente pattern in dir command | grep pattern cerca pattern nel risultato dell'esecuzione di command locate file trova tutte le occorrenze di file

Potrebbero piacerti anche