Indice

Esercitazione 3

Esercizio 1: ridefiniamo 'cd'

Ridefinire il builtin cd usando una funzione cd in modo che con 0 o 1 parametri si comporti come il builtin cd mentre con 2 parametri, ad esempio:

cd old new

sostituisca tutte le occorrenze di old nella working directory corrente con new e poi cerchi di spostarsi nel path cosi' generato (se esiste ed e' una directory).

Gestire anche le situazioni di errore. Utilizzare il costrutto case per discriminare fra il numero dei parametri forniti alla funzione (vedi esempio nella lezione 3 su bash).

Esercizio 2: icd, interactive cd

Definire la funzione icd (interactive cd) in modo che elenchi le directory presenti nella directory corrente e chieda inrterattivamente all'utente in qualse vuole spostarsi. Ad esempio:

bash:~$ icd
1) pippo/
2) pluto/
3) paperone/
Quale scegli?
3
bash:~/paperone$

Si usi il costrutto select per interagire con l'utente settando opportunamente la variabile di prompt.

Avanzato: estendere icd in modo che accetti come parametro il path della directory in cui effettuare la scelta.

Esercizio 3: printpath

Definire la funzione printpath che stampa una per linea tutte le directory presenti nella variabile di ambiente PATH (separatore ':') una per linea. Ad esempio

 
bash:~$ printpath
/home/susanna/bin
/usr/local/bin
/usr/bin
/usr/X11R6/bin
/bin
/usr/games
/opt/gnome/bin
/opt/kde3/bin
/home/susanna/local/bin
.
bash:~$

Attenzione: il separatore ':' deve essere rimosso.

Esercizio 4: printusr

Definire una funzione printusr che stampi i nomi dei primi 10 utenti della macchina ordinati lessicograficamente (vedi file /etc/passwd) con la loro home. Ad esempio

bash:~$ printusr
at:/var/spool/atjobs
bin:/bin
daemon:/sbin
francy:/home/francy
ftp:/srv/ftp
games:/var/games
gdm:/var/lib/gdm
irc:/usr/lib/ircd
ldap:/var/lib/ldap
lp:/var/spool/lpd
bash:~$

Chi riesce a farlo in meno linee di codice?

Esercizio 5: opzioni : mykeyselect

Scrivere uno script

mykeyselect  [-a][-b barg][-c carg] file

file contiene su ogni riga delle coppie

chiave valore

dove valore e' un valore numerico. Lo script stampa la lista ordinata delle N chiavi di minor valore nel file. N e' pari a 4 se l'opzione -b non e' specificata altrimenti N=barg. Se -a e' specificata si stampano le chiavi di maggior valore e non quelle di monor valore. Se e' specificata l'opzione -c, vengono ignorate tutte le righe che contengono carg.

Le gestione delle opzioni deve avere le seguenti proprieta':

mykeyselect -b 20 -a filename
mykeyselect -c -a -b 30 filename
mykeyselect -ac gigi
mykeyselect -b20 -a filename
mykeyselect -cgigi -a -b 30 filename
mykeyselect -acgigi filename

Suggerimenti: Utilizzare sort per effettare il sorting, in particolare verificare sul man le opzioni -n e -k. Utilizzare i builtin shift e getopts per effettuare il persing della linea di comando. Essendo builtin le informazioni in linea si possono accedere da man bash. Una spiegazione piu' accurata del funzionamento di getopts (con esempi) e' disponibile in linea qua oppure qua.

Esercizio 6: interi : totdu

Sviluppare uno script:

totdu [<dir1> ... <dirN>]

che per ogni argomento che sia una directory stampa lo spazio utilizzato dalla directory e da tutte le sue sottodirectory, in byte e Kbyte (se >1KB) oppure in byte e Mbyte (se >1MB). Se non viene specificata alcuna directory si forniscono informazioni sulla directory corrente. Ad esempio:

bash:~$ totdu ciccio pippo
ciccio: Totale 18098176 byte 17 MB
pippo: Totale 14336 byte 14 KB

Suggerimenti: Utilizzare du per i byte occupati. Il comando cut puo' essere utile per selzionare un'opportuna colonna dell'output. Notare che nelle espressioni intere si puo' specificare un numero in base diversa da 10 con la notazione base#numero es: 16#400 per 1024.

Esercizio 7: self exec shell

Provare ad eseguire:

#!/bin/bash
# self-exec.sh
echo "This line appears ONCE in the script, yet it keeps echoing."
echo "The PID of this instance of the script is still $$."
#     The same shell always running
echo "==================== Hit Ctl-C to exit ===================="
sleep 1

exec $0   

echo "This line will never echo!"  # Why not?

exit 0

che succede? perche?

Esercizio 8: makecmd: a simple make

Implementare una funzione makecmd in grado di interpretare un singolo costrutto del tipo

target: source1 .. sourceN
       cmd1
       ....
       cmdK

fornito sullo standard input secondo la usuale semantica 'make' (la lista di comandi viene eseguita se il target non esiste oppure se e' stato modificato l'ultima volta in tempi precedenti rispetto ad almeno uno dei source nella dependency list, ogni comando viene prima stampato su stdout e poi eseguito). Se un source nella dependency list non esiste si considera la dipendenza verificata (!= semantica make). Ad esempio:

bash:~$ more makefile
a : b c d
    echo "Sto eseguendo!"
bash:~$ makecmd < makefile
echo "Sto eseguendo!"
Sto eseguendo!

Utilizzare il builtin read per leggere dallo standard input, ed eval per invocare la esecuzione di un comando della lista.