Pages

Subscribe:

mercoledì 22 gennaio 2014

ESERCIZI SVOLTI TERMINALE BASH MAC LINUX

1 Creare uno script che produca un log che registri tutti i processi lanciati dall'avvio dello
script con l'indicazione di quale Ë il parent che li ha lanciati
("il processo XY ha lanciato il processo ZZ").

#!/bin/bash
export IFS=$'\n';
pid=(`ps axo pid`)
ppid=(`ps axo ppid`)
lenpid=${#pid[*]}
i=1
while [ $i -lt $lenpid ]
do
            echo "il processo ${ppid[$i]} ha lanciato il processo ${pid[$i]}">>log
            let i++
done
pid=(`ps axo pid,ppid | awk '{print $1}'`)
k=0
for k in ${pid[*]}
do
            printf "%s\n" $k
            let k++
done

Trasformare ricorsivamente tutti i nomi di file contenuti in una directory sostituendo
i caratteri maiuscoli con i minuscoli.

#!/bin/bash
for file in *
do
            fnome=`basename $file`
            n=`echo $fnome | tr a-z A-Z`
            if [ "$fnome" != "$n" ]
            then
                       mv $fnome $n
            fi
done

1 Creare uno script che aggiorni continuamente l'ora completa dei secondi.

#!/bin/bash
while :
do
            date
            sleep 1
done

3 Creare uno script che al passare del tempo disegni un grafico della
percentuale di CPU utilizzata da un processo di PID dato come parametro. Fare in modo che
l'intervallo di campionamento della grandezza sia un parametro dello script.

#!/bin/bash
echo "I pid presenti sono:"  
ps axo pid
echo "Scegli un pid:"
read pid   
while :
do
            cpu=`ps axo pid,pcpu | grep $pid | awk '{print $2}'`
            arrotondato=$(echo $cpu | awk '{printf("%.0f\n", $1)}')
            echo "Il valore è $arrotondato"
            i=0
            while [ "$i" != "$arrotondato" ]
            do
                       echo -n "_" 
                       let i++
            done
            echo -e ""
            sleep 1
done

3 Due file hanno lo stesso contenuto a parte una o più variazioni nella loro parte
iniziale di lunghezza fissa. Fare uno script che dia informazioni sull'identità del
contenuto indipendentemente dalla variazione dell'intestazione dei file.

#!/bin/bash
echo "Il numero di linee del file 1 è:"
wc -l $1
echo "Il numero di linee del file 2 è:"
wc -l $2
echo "Le differenze del file 2 rispetto all'1 sono:"
diff $1 $2 | egrep '^> .*'

4 Creare uno script bash che sia in grado di esaminare i file di un certo numero di directory elencate dall'utente in un file e di proporre l'eliminazione dei file doppioni (ovvero di evitareche di uno stesso file - indipendentemente dal nome - esistano più copie).

#!/bin/bash
echo "Le cartelle elencate nel file di testo sono:"
cat -n $1
while [ "$cartella" != "0" ]
do
            echo "Inserisci cartella nella quale cercare (inserire 0 per uscire dallo script):"
            cd
            read cartella
            cd home/administrator/$cartella
            ls -a $cartella > file.txt
            chmod 755 file.txt
            cat file.txt
            a=$(wc -l "file.txt")
            echo "$a"
            lista=`find "$dir" -type f -exec md5sum '{}' \; | sort`    
            md5sum_com=`echo "$lista" | awk '{print $1}' | uniq -d`        
done

5 Un disco dal quale dobbiamo copiare un gran numero di file è guasto e va in
errore quando viene letto di continuo oltre un certo numero di secondi.
Per risolvere il problema fare in modo che la copia di una grossa directory
in un altra sia fatta fermandosi per un certo numero di secondi A ogni numero
di secondi prefissato B. Nota: non è necessario copiare realmente grosse
directory per dimostrare la funzionalità della soluzione.

#!/bin/bash

tempolimite=0
pausa=5

echo "Per sospendere il processo di copia premere CTRL + C. Il numero di secondi trascorsi è:"
a=$(date +%s)
echo "$a"
lung=${#a}
echo "La lunghezza della stringa è $lung!"
echo "Inserire valori da estrarre in modo che rimanga solo l'ultimo carattere (ad es. la lunghezza è 10 estraggo 9 caratteri):"
read car
sec=${a:$car}
while :
do      
            i=$a
            if [ $i == 0 ]
            then
                       sleep $pausa
            else
                       cp -a $1 $2
            fi
            break
done

Elencare tutti gli script bash contenuti dentro la directory /etc ordinandoli
per numero di righe (escludendo le righe di commento e le righe vuote)

#!/bin/bash
cd
cd /etc
ls *.sh | sort

6 Fare uno script che permetta a chiunque di aggiungere dati in coda ad un vostro
file senza permettere di visualizzare il suo contenuto.
#!/bin/bash
echo "Scrivere quello che si vuole aggiungere in coda al file testo. Per uscire premere 0!"
chmod 333 testo.txt
while [ "$files" != "0" ]
do
            read files
            if [ "$files" != "0" ]   
            then              
                       a=$files
                       echo $a >> testo.txt 
            fi
done

6 Scrivere uno script che verifica l'esistenza di una certa directory
ed esegue nel proprio contesto gli script contenuti nella directory che
hanno uno schema di nome prefissato (es. nome_scelto_da_te_01,
nome_scelto_da_te_02, ecc, nell'ordine suggerito dal numero).

#!/bin/bash
cd
if [ -d Documenti ]
then
            echo "Documenti esiste."
            cd Documenti
            ls *.sh | sort > lista.txt
            cat lista.txt
            lung=$(wc -l lista.txt | awk '{printf $1}')
            echo "$lung"
            k=1    
            i=0
            while [ $i -lt $lung ]
            do
                       script=$(head -$k lista.txt | tail -1)
                       ./$script
                       let i++
                       let k++
            done
else
    echo "Non esiste"
fi

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

#!/bin/bash
echo "Per uscire dallo script premere CTRL+C!"
i=0
while :
do
            let i++
            sleep 1
            echo "Il numero incrementato è $i!"
done

7 Scrivere in bash un filtro che stampi allo standard output una parola
ogni due presenti allo standard input.

#!/bin/bash
cat testo.txt | tr " " "\n" > elenco.txt
chmod 755 elenco.txt
cat elenco.txt
righe=$(wc -l elenco.txt | awk '{print $1}')
echo "$righe"
echo "Le parole stampate 1 ogni 2 sono:"
i=1
while [ "$i" -le "$righe" ]
do
            a=$(head -$i elenco.txt | tail -1)
            echo "$a"
            i=$(($i+3))
done  

8 Scrivere in bash uno script interattivo per la raccolta delle generalità di
un gruppo di persone.
Lo script, una volta lanciato,
a) deve chiedere all'utente una password per proseguire nell'inserimento,
uguale per tutti gli utenti ed invisibile mentre è inserita;
b) non deve essere interrompibile tramite comandi dalla tastiera;
c) deve aggiungere le generalità ad un file leggibile solo dall'amministratore
(una riga per persona);
d) deve permettere la terminazione della fase di inserimento dati tramite
scrittura della stessa password, anch'essa invisibile mentre è inserita;

#!/bin/bash
password=accedi
echo "Inserire il numero di utenti da mettere in archivio:"
read numero
i=1
while [ $i -le $numero ]
do
            read nome    
            echo "Benvenuto utente $nome!"
            echo "Per accedere digita la password:"
            read -s verifica
            if [ $verifica == $password ]
            then   
                       echo "Inserisci le generalità (nel seguente formato: nome cognome, data di nascita, via e numero civico, numero di telefono):"
                       read generalita
                       a=$generalita
                       echo $a >> elenco.txt
                       chown danilo elenco.txt
                       chmod 422 elenco.txt
                       echo "Inserisci di nuovo la password per uscire:"
                       read -s pass1
                       if [ $pass1 != $password ]
                       then
                                   while [ $pass1 != $password ]
                                   do
                                               echo "Password sbagliata!"
                                               echo "Inserire nuovamente password!"
                                               read -s pass1
                                   done
                       fi
            else
                       echo "Password sbagliata!"
                       echo "Reimmettere password:"
                       read -s verifica
                       if [ $verifica != $password ]
                       then
                                   echo "Mi dispiace utente $i il suo account è stato bloccato!"
                       fi
            fi
let i++
done
                                  
9 Un utente apre più sessioni terminale (es.finestre) su una stessa macchina.
Scrivere uno script bash da far girare in una nuova finestra
che identifichi quella tra le altre finestre che è stata più recentemente
attiva (es. ha prodotto dell'output).     

#!/bin/bash
who | grep 'pts/*' >> testo.txt
chmod 755 testo.txt
a=$(wc -l testo.txt | awk {'print $1'})
let a--
terminale=$(head -$a testo.txt | tail -1)
echo "Il terminale più recente è: $terminale"

10 Uno script A svolge delle operazioni (es.incrementa un contatore).
Costruire uno script B che costringa ad intervalli regolari
lo script A a stampare allo standard output il risultato dell'operazione.
Lo script A può essere modificato per ottenere lo scopo prefisso.
Non è permesso usare file temporanei per lo svolgimento dell'esercizio.
I due script devono essere lanciati indipendentemente.

#!/bin/bash
i=0
while [ $i -le 20 ]
do
            let i++
            ./scriptb.sh
            echo "$i"
done

#!/bin/bash
sleep 1

11 Creare un distributore automatico di carte del vostro gioco preferito.

#!/bin/bash
var=( goku gohan vidal goten trunks pam vegeta goku2 goku3 junior goku4 vegeta2 vegeta3 gohan2 goten2 trunks2 gogeta crilin bulma kiki )
echo "Inserire numero di acquirenti:"
read acquirenti
i=1
while [ $i -le $acquirenti ]
do
            echo "Benvenuto acquirente $i!"
            echo "Inserisci euro a disposizione (costo di una carta 1 euro):"
            read euro
            k=1
            while [ $k -le $euro ]
            do
                       let "carta= RANDOM % 20"
                       echo "Complimenti hai vinto ${var[$carta]}!"
                       let k++
            done
let i++
done

12 Scrivere uno script bash di nome "script1" che a partire da una
directory (data come primo parametro) trovi tra tutte le sue
sottodirectory di qualunque livello quella che contiene il maggior
numero di elementi (contando solo i  file regolari). Sia A tale
directory. Nell'ambito dello stesso script creare in essa una directory
avente come nome una stringa data come secondo parametro e spostare in
essa tutti i file che sono entries della directory A e che contenengono
nel loro nome o al loro interno tale stringa.

Per effettuare un test, utilizzare come primo parametro una copia della
directory /home/franco/esame12 e come secondo parametro la stringa
"esame".

#!/bin/bash
cd $1
find -type d | tr '' '\n' > elenco.txt
chmod 755 elenco.txt
a=$(wc -l elenco.txt | awk '{print $1}')
i=2
k=1
max1=0
while [ "$i" -le "$a" ]
do      
            cartella=$(sed -n "${i}p" elenco.txt)
            cd $cartella
            find -type f > file1.txt
            chmod 755 file1.txt
            b=$(wc -l file1.txt | awk '{print $1}')
            let b--
            max=$b
            if [ "$max" -gt "$max1" ]
            then
                       max1=$max
                       cartella_scelta=$cartella
            fi
            cd
            cd Documenti/esame12/$1
let i++
let k++
done
echo "La cartella che contiene più file, cioè $max1, è $cartella_scelta!"

13 Scrivere uno script bash di nome "pscmd" che prenda come argomento il nome
di un comando e che restituisca la somma delle percentuali di CPU
utilizzate da tutte le istanze di tale comando in esecuzione
nel sistema da parte di qualsiasi utente al momento del lancio dello script.

#!/bin/bash
$1
a=$(pidof $1)
echo "La cpu usata è `ps -p $a -o%cpu=`"

15 Scrivere uno script che accetta come argomento il nome di una directory e
calcola una stringa che è indice dell'integrità della directory, in modo che, se
rieseguendo lo stesso script sulla stessa directory il risultato non cambia,
si abbia la certezza che la struttura interna della directory e i suoi
contenuti non sono stati modificati.

#!/bin/bash
echo "$1"
echo -n "cane" | md5sum

15 Scrivere uno script che produca una lista dei propri processi ordinata
secondo il numero di file aperti da ciascuno di essi.

#!/bin/bash
lsof | sort -k 8 -n

16 Scrivere uno script che giri sul proprio Mac e che misuri sia il carico medio
della CPU della macchina su cui viene lanciato sia quello della CPU della macchina
hplinux2.unile.it e lanci sulla macchina che ha il minor carico un certo
comando dato come parametro. Suggerimento: usare il comando ssh.

#!/bin/bash
cpumac=$(ps -a -o %cpu='' | tr '\n' '+' | sed 's/+$//' | tr '\,' '.' | bc)
echo "$cpumac"
echo "Inserire nome utente"
read nome
cpulinx=$(ssh $danilo@hplinux2.unile.it ps -a -o %cpu='' | tr '\' '+' | sed 's/+$//' | bc)
echo "$cpulinux"
if [[ $cpumac -ge $cpulinux ]]
then
            echo "Eseguo il comando su mac!"
            $1
else
echo "Eseguo il comando su linux!"
            ssh $nome@hplinux2.unile.it $1
fi

17 Scrivere uno script bash che accetta come argomento il nome di una directory e
stampi a terminale il numero di inode più alto presente nella directory e
in tutte le sue sottodirectory.

#!/bin/bash
cd $1
ls -li | sort -k1 -n > file.tmp
chmod 755 file.txt
inode=$(tail -1 file.txt | awk '{print $1}')
find -type d > file1.txt
chmod 755 file1.txt
cat file1.txt
a=$(wc -l file1.txt | awk '{print $1}')
i=2
while [ "$i" -le "$a" ]
do
            cartella=$(head -$i file1.txt | tail -1)
            echo "$cartella"
            cd $cartella
            ls -li | sort -k1 -n > file.tmp
            cat file.tmp
            inode1=$(tail -1 file.txt | awk '{print $1}')
            cd ..
            if [ "$inode" -lt "$inode1" ]
            then
                       max=$inode1
            fi
            let i++
done
echo "L'inode maggiori sono $max"
17 Scrivere uno script bash che visiti periodicamente una certa pagina html via
http e stampi a terminale un messaggio quando trova una certa stringa nella
pagina.
Intervallo della periodicità, indirizzo della pagina e stringa siano passati
come parametri allo script.

#!/bin/bash
i=1
while :
do
            sleep 5
            finded=$(curl "$1" | grep -o -i "$2" | wc -l)
            if [ "$i" -le "$finded" ]
            then
                       echo "Parola trovata $finded volte"
            fi
done

18 Fare in modo che il proprio prompt principale indichi il numerodi processi attivi nel sistema al momento.

#!/bin/bash
ps > file.txt
chmod 755 file.txt
a=$(wc -l file.txt | awk '{print $1}')
let a--
echo "I processi attivo sono $a!"

19 Creare uno script chiamato 'limita' che controlli con un periodo A i processi che
l'utente ha generato con l'esecuzione di programmi contenuti in una cartella B
e faccia in modo che, quando la somma delle percentuali di CPU utilizzate
da tali processi supera una certa soglia C, sia abbassata la priorità del
processo che tra essi utilizza maggiormente la CPU.
Dare A, B e C come parametri allo script.

#!/bin/bash
max1=0
tot=0
k=0
cd $2
while [ $k -le $1 ]
do
            find . -name "*.sh" > file.txt
            chmod 755 file.txt
            cat file.txt
            a=$(wc -l file.txt | awk '{print $1}')
            i=1
            while [ $i -le $a ]
            do
                       prog=$(head -$i file.txt | tail -1)
                       $prog
                       echo ${prog:2} > elenco.txt
                       chmod 755 elenco.txt
                       nuovoprog=$(head -$i elenco.txt | tail -1)
                       ps aux | grep $nuovoprog | awk '{print $2}' > file1.txt
                       chmod 755 file1.txt
                       let i++
            done
            uniq file1.txt
            c=$(wc -l file1.txt | awk '{print $1}')
            j=1
            while [ $j -le $c ]
            do
                       prog1=$(head -$j file1.txt | tail -1)          
                       ps aux | grep $prog1 | awk '{print $3}' > ram.txt
                       chmod 755 ram.txt
                       cat ram.txt                
                       d=$(wc -l ram.txt | awk '{print $1}')
                       y=1
                       while [ $y -le $d ]
                       do
                                   ram=$(head -$i ram.txt | tail -1)
                                   echo $ram | awk '{printf("%.0f\n", $1)}' > ramarr.txt
                                   let y++
                       done
                       cont=$(wc -l ramarr.txt | awk '{print $1}')
                       r=1
                       while [ $r -le $cont ]
                       do
                                   somma=$(head -$j ramarr.txt | tail -1)
                                   tot=$((tot += somma))
                                   max=$somma
                                   if [ $max1 -le $max ]
                                   then
                                               max1=$max
                                               processo=$prog1
                                   fi
                                   if [ $3 -le $tot ]
                                   then
                                               renice -20 $processo
                                   else
                                               echo "E' tutto ok!"
                                   fi
                                   let r++
                       done
            done
let k++
done
           
20 Creare uno script chiamato 'contablocchi' che scriva allo standard output la somma del numero di blocchi occupati da tutti i file in cui numero di inode ricade nell'intervallo tra A e B.
Dare A e B come parametri allo script.

#!/bin/bash
cd
ls -li > file.txt
chmod 755 file.txt
d=$(wc -l file.txt | awk '{print $1}')
j=2
while [ $j -le $d ]
do
            inode=$(head -$j file.txt | tail -1 | awk '{print $1}')
            if [ "$inode" -gt "$1" ]  && [ "$inode" -lt "$2" ]
            then
                                   echo "$inode"
            fi
            let j++
done
find -type d > file1.txt
chmod 755 file1.txt
a=$(wc -l file1.txt | awk '{print $1}')
i=2
while [ "$i" -le "$a" ]
do
            cartella=$(head -$i file1.txt | tail -1)
            echo ${cartella:1} >> elenco.txt
            chmod 755 elenco.txt
            let i++
done
g=$(wc -l elenco.txt | awk '{print $1}')
h=1
while [ "$h" -le "$g" ]
do
            cartella1=$(head -$h file1.txt | tail -1)
            cd $cartella1
            ls -li > file.txt
            chmod 755 file.txt
            d1=$(wc -l file.txt | awk '{print $1}')
            k=2
            while [ $k -le $d1 ]
            do
                       inode1=$(head -$k file.txt | tail -1 | awk '{print $1}')
                       cd
                       if [  "$inode1" -le "$1" ] && [  "$inode1" -ge "$2" ]
                       then
                                   echo "$inode1"
                       fi
            let k++
            done
            cd
            let h++
done

20 Creare uno script chiamato 'firma' che scriva allo standard output una stringa
associata alla directory A con la proprietà che tale stringa rimanga immutata se e solo se, anche 
nel caso in cui la directory cambi di posizione, nessuno dei file contenuti,
incluse le directory, viene modificato o cambiato.
Dare A come parametro allo script.

#!/bin/bash
echo "$1"
a=$(ls -l | md5sum)
echo "$a"

21 Creare uno script chiamato "creacartella" che prende come parametro un nome, crea una cartella che ha tale nome dotata della proprietà che chiunque possa depositarvi dei file potendoli in seguito cancellare ma non potendo cancellare quelli depositativi da altri.

#!/bin/bash
mkdir $1
chmod 766 $1

21 Creare uno script chiamato "consuma" che esegua il programma ps un certo numero di volte fermandosi quando ha consumato nel complesso 1 secondo di tempo di CPU.

#!/bin/bash
i=1
while [ "$SECONDS" -le "$i" ]
do
            ps
done

22 Creare uno script chiamato "elimina", che elimini dal sistema i file regolari passati ad esso come argomento e tutti i link (hard e soft) a tali file.

#!/bin/bash
cd

 for i in $@; do
     echo -e "$i"
            inode=$(find -type f -name "$i" -exec sh -c 'ls -di "$0" | head -1' {} \; | awk '{print $1}')
            echo "$inode"
            inode1=$(find -type l -exec ls -lai {} \; | grep "$i" | awk  '{print $1}')
            echo "$inode1"
            find -inum "$inode1" -exec rm {} \;
            find -inum "$inode" -exec rm {} \;
  done

23 Creare uno script chiamato "containodes" che conta il numero di inodes utilizzati dal file system nel quale è stato salvato.

#!/bin/bash
echo "Il percorso del file è:"
pwd
cd
cd /home
echo "Il numero di inode è:"
ls -li | head -2 | tail -1 | awk '{print $1}'

23 Creare uno script bash, chiamato "cifra", che applichi ad uno o più file di testo passati come argomento la cifratura consistente nel trasformare:
1) le lettere dalla A alla M in lettere dalla N alla Z e viceversa;
2) le lettere dalla a alla m in lettere dalla n alla z e viceversa.

#!/bin/bash
lis=1
for i in $@; do
            cat $i | tr ' ' '\n' > nuovo.txt
            chmod 755 nuovo.txt
            cont=$(wc -l nuovo.txt | awk '{print $1}')
            p=1
            while [ "$p" -le "$cont" ]
            do
                       stringa=$(head -$p nuovo.txt | tail -1)
                       q=0
                       lungstringa=${#stringa}
                       k=0
                       while [ $k -lt $lungstringa ]
                       do
                                   min=`expr $lungstringa - 1`
                                   stringanuova=$(echo ${stringa:$k})
                                   car=$(echo ${stringanuova} | cut -c1-1)
                                   if [ "$car" == "A" ] || [ "$car" == "B" ] || [ "$car" == "C" ] || [ "$car" == "D" ] || [ "$car" == "E" ] || [ "$car" == "F" ] || [ "$car" == "G" ] || [ "$car" == "H" ] || [ "$car" == "I" ] || [ "$car" == "L" ] || [ "$car" == "M" ]
                                   then
                                               echo ${stringanuova} | cut -c1-1 | tr "A-M" "N-Z" | tr -d "\n" >> testo$lis.txt
                                               chmod 755 testo$lis.txt
                                               let q++
                                   fi        
                                   if [ "$car" == "N" ] || [ "$car" == "O" ] || [ "$car" == "P" ] || [ "$car" == "R" ] || [ "$car" == "S" ] || [ "$car" == "T" ] || [ "$car" == "U" ] || [ "$car" == "V" ] || [ "$car" == "Z" ] || [ "$car" == "X" ] || [ "$car" == "Q" ]
                                   then
                                               echo ${stringanuova} | cut -c1-1 | tr "N-Z" "A-M" | tr -d "\n" >> testo$lis.txt
                                               chmod 755 testo$lis.txt
                                               let q++
                                   fi
                                   if [ "$car" == "a" ] || [ "$car" == "b" ] || [ "$car" == "c" ] || [ "$car" == "d" ] || [ "$car" == "e" ] || [ "$car" == "f" ] || [ "$car" == "g" ] || [ "$car" == "h" ] || [ "$car" == "i" ] || [ "$car" == "l" ] || [ "$car" == "m" ]
                                   then
                                               echo ${stringanuova} | cut -c1-1 | tr "a-m" "n-z" | tr -d "\n" >> testo$lis.txt
                                               chmod 755 testo$lis.txt
                                               let q++
                                   fi        
                                   if [ "$car" == "n" ] || [ "$car" == "o" ] || [ "$car" == "p" ] || [ "$car" == "q" ] || [ "$car" == "r" ] || [ "$car" == "s" ] || [ "$car" == "t" ] || [ "$car" == "u" ] || [ "$car" == "v" ] || [ "$car" == "z" ] || [ "$car" == "x" ]
                                   then
                                               echo ${stringanuova} | cut -c1-1 | tr "n-z" "a-m" | tr -d "\n" >> testo$lis.txt
                                               chmod 755 testo$lis.txt
                                               let q++
                                   fi
                                   if [ "$car" == "." ] || [ "$car" == "!" ] || [ "$car" == "," ] || [ "$car" == ":" ] || [ "$car" == "1" ] || [ "$car" == "2" ] #ecc ecc
                                   then
                                               echo $car >> testo$lis.txt
                                   fi
                                   if [ "$k" == "$min" ]
                                   then
                                               echo -e >> testo$lis.txt
                                   fi                                
                       let k++
                       done
            let p++
            done
echo -e
echo "Il file $i trasformato è:"
cat testo$lis.txt | tr '\n' ' '
let lis++
done
echo –e

25 Scrivere in bash uno script che confronti due directory passate come parametri e ne
riveli con analisi ricorsiva:
a) le differenze di struttura (directory, sottodirectory e file presenti o assenti in una e non nell'altra);
b) differenze nel contenuto dei file corrispondenti anche a parità di struttura;

Suggerimento (non vincolante, possono esistere molti metodi alternativi): si consideri il comando comm

#!/bin/bash
cd $1
ls -l > elenco1.txt
chmod 755 elenco1.txt
echo "I file e cartelle contenute in $1 sono:"
cat elenco1.txt
find . -type d > nuovo1.txt
chmod 755 nuovo1.txt
a1=$(wc -l nuovo1.txt | awk '{print $1}')
max1=$a1
let a1--
echo "Le cartelle appartenenti alla cartella $1 sono $a1!"
cat nuovo1.txt
find . -type f > file1.txt
chmod 755 file1.txt
b1=$(wc -l file1.txt | awk '{print $1}')
echo "I file regolari presenti in $1 e in tutte le sottocartelle sono $b1!"
cat file1.txt
i=2
while [ "$i" -le "$max1" ]
do
            cartella1=$(head -$i nuovo1.txt | tail -1)
            cart1=$(echo ${cartella1:2})
            cd $cart1
            echo "I file contenuti in $cart1 sono:"
            ls -l
            let i++
            cd
            cd Documenti/esame25/$1
done
echo "**************************************************************"
cd
cd Documenti/esame25/$2
ls -l > elenco2.txt
chmod 755 elenco2.txt
echo "I file e cartelle contenute in $2 sono:"
cat elenco2.txt
find . -type d > nuovo2.txt
chmod 755 nuovo2.txt
a2=$(wc -l nuovo2.txt | awk '{print $1}')
max2=$a2
let a2--
echo "Le cartelle appartenenti alla cartella $2 sono $a2!"
cat nuovo2.txt
find . -type f > file2.txt
chmod 755 file2.txt
b2=$(wc -l file2.txt | awk '{print $1}')
echo "I file regolari presenti in $2 e in tutte le sottocartelle sono $b2!"
cat file2.txt
k=2
while [ "$k" -le "$max2" ]
do
            cartella2=$(head -$k nuovo2.txt | tail -1)
            cart2=$(echo ${cartella2:2})
            cd $cart2
            echo "I file contenuti in $cart2 sono:"
            ls -l
            let k++
            cd
            cd Documenti/esame25/$2
done

26 Scrivere in bash uno script che realizzi il seguente sistema di back-up ogni volta che è lanciato:

a) apre una directory il cui nome contenga la data, l'ora e il minuto del lancio dello script;
b) solo per il primo lancio in tale directory copia interamente il contenuto di una directory passata
come parametro allo script;
c) nei lanci seguenti dello script copia i file se sono cambiati rispetto alla prima volta che sono
stati copiati e invece ne fa solo un hard link all'ultima copia fatta se non sono cambiati.
d) i file nuovamente creati nella directory A siano trattati come i file cambiati.

Esempio:
la directory A (contenente i file B, C e D) viene passata come parametro. Al primo lancio viene
creata la directory 200712140930-A in cui vengono copiati B, C e D. Al secondo lancio, viene
creata la directory 200712140931-A. Supponendo che il B contenuto nella directory A sia cambiato
rispetto a quello copiato nella directory 200712140930-A (mentre C e D siano rimasti invariati),
si faccia in 200712140931-A una copia del B di A e si mettano in 200712140931-A semplicemente degli
hard link ai file C e D contenuti in 200712140930-A.

#!/bin/bash
giri=2
primo=1
secondo=2
i=1
while [ "$i" -le "$giri" ]
do
            if [ $i == $primo ]
            then
                       data=$(date +%Y%m%d%H%M%S)
                       mkdir $data-A
                       cp /home/administrator/Documenti/esame26/$1/B.txt /home/administrator/Documenti/esame26/$data-A
                       cp /home/administrator/Documenti/esame26/$1/C.txt /home/administrator/Documenti/esame26/$data-A
                       cp /home/administrator/Documenti/esame26/$1/D.txt /home/administrator/Documenti/esame26/$data-A
                       cd A
                       echo "ciao" >> B.txt
                       fileoB=$(md5sum B.txt)
                       echo "****$fileoB"
                       fileoC=$(md5sum C.txt)
                       fileoD=$(md5sum D.txt)
                       cd ..
            fi
            sleep 0.5
            if [ $i == $secondo ]
            then
                       data1=$(date +%Y%m%d%H%M%S)
                       mkdir $data1-A
            fi
            if [ $i == $secondo ]
            then
                       cd $data-A
                       fileB=$(md5sum B.txt)
                       echo "****$fileB"
                       fileC=$(md5sum C.txt)
                       fileD=$(md5sum D.txt)
                       cd ..
                       if [ "$fileB" != "$fileoB" ]
                       then
                                   cp /home/administrator/Documenti/esame26/$1/B.txt /home/administrator/Documenti/esame26/$data1-A
                                   ln /home/administrator/Documenti/esame26/$1/C.txt /home/administrator/Documenti/esame26/$data1-A/C1.txt
                                   ln /home/administrator/Documenti/esame26/$1/D.txt /home/administrator/Documenti/esame26/$data1-A/D1.txt
                       fi
                       if [ "$fileC" != "$fileoC" ]
                       then
                                   cp /home/administrator/Documenti/esame26/$1/C.txt /home/administrator/Documenti/esame26/$data1-A
                                   ln /home/administrator/Documenti/esame26/$1/B.txt /home/administrator/Documenti/esame26/$data1-A/B1.txt
                                   ln /home/administrator/Documenti/esame26/$1/D.txt /home/administrator/Documenti/esame26/$data1-A/D1.txt
                       fi
                       if [ "$fileD" != "$fileoD" ]
                       then
                                   cp /home/administrator/Documenti/esame26/$1/D.txt /home/administrator/Documenti/esame26/$data1-A
                                   ln /home/administrator/Documenti/esame26/$1/B.txt /home/administrator/Documenti/esame26/$data1-A/B1.txt
                                   ln /home/administrator/Documenti/esame26/$1/C.txt /home/administrator/Documenti/esame26/$data1-A/C1.txt
                       fi
            fi
            let i++
done

27 Utilizzando il dizionario /usr/share/dict/words creare uno script che prenda come argomento un numero intero N e componga una frase estraendo a caso N parole dal dizionario.

#!/bin/bash
WORDFILE=/usr/share/dict/words
RANDOM=$$;
echo "Inserire il numero di parole da fare:"
read numero
i=1
while [ $i -le $numero ]
do
            # seed random from pid
            # using cat means wc outputs only a number, not number followed by filename
            lines=$(cat $WORDFILE  | wc -l);
            rnum=$((RANDOM*RANDOM%$lines+1));
            sed -n "$rnum p" $WORDFILE;
            let i++
done

27 Dato come input un elenco di file, questo script interrogherà ciascun file per controllare quale tipo di compressione è stata ad esso applicata.
Lo script, quindi, dovrà invocare automaticamente l'appropriato comando di decompressione (gunzip, bunzip2, unzip, uncompress o altro). Se, tra i file indicati, ve ne dovessero essere di non compressi, lo script dovrà visualizzare un messaggio d'avvertimento e non effettuare, su tali file, nessun'altra azione.

#!/bin/bash
a=$(wc -l $1 | awk '{print $1}')
i=1
while [ $i -le $a ]
do
            file=$(head -$i $1 | tail -1)
            echo "***$file"
            file1=$(echo ${file:(-3)})
            file2=$(echo ${file:(-4)})
            file3=$(echo ${file:(-7)})
            echo "****$file1"
            if [ "$file1" == ".gz" ]
            then
                       cd
                       nome=$(find -name "$file")
                       nfile=$(echo ${nome:1})
                       echo "$nfile"
                       gzip -d /home/administrator$nfile
            fi
            if [ "$file2" == ".bz2" ]
            then
                       cd
                       nome=$(find -name "$file")
                       nfile=$(echo ${nome:1})
                       echo "$nfile"
                       bunzip2 /home/administrator$file
            fi
            if [ "$file3" == ".tar.gz" ]
            then
                       cd
                       nome=$(find -name "$file")
                       nfile=$(echo ${nome:1})
                       echo "$nfile"
                       gzip -dc /home/administrator$file
            fi
            let i++
done

28 Fare in modo che alla chiusura di ciascuna propria sessione di lavoro, la lista dei comandi dati fino a quel momento sia salvata automaticamente in un file il cui nome sia del tipo 200802151120-SessioneLavoro.txt

#!/bin/bash
trap $(history > $(date +%Y%m%d%H%M)-Sessioneavoro.txt) SIGHUP SIGINT SIGQUIT SIGABRT SIGKILL SIGTERM

28 Verificare se tra tutti i file con SUID settato presenti nel sistema esiste una coppia di link allo stesso inode.

#!/bin/bash
find -xdev -type f -perm +u=s -print -exec ls -li {} \; > suidist.txt
find -xdev -type f -perm +u=s -print -exec ls -li {} \; |awk '{print $1}' > inodelist.txt
a=$(wc -l inodelist.txt | awk '{print $1}')
i=1
while [ $i -le $a ]
do
            inode=$(head -$i inodelist.txt | tail -1)
            echo "L'inode al SUID da verificare è $inode!"
            cd
            stringa=$(find -inum "$inode")
            if [ ! -z "$stringa" ]
            then
                       echo "Non ci sono hard link al SUID!"
            else
                       echo "L'hard link al SUID è $stringa!"
            fi
let i++
done

29 Scrivere uno script che tracci al terminale il grafico relativo all'evoluzione temporale del totale della memoria reale (RSS, Resident Set Size) utilizzata dai processi del sistema.

#!/bin/bash
while :
do
            ps -a -orss= > lista.txt
            mem=$(head -2 lista.txt | tail -1)
            echo "***$mem"
            i=0
            while [ "$i" -lt "$mem" ]
            do
                       echo -n "*"
                       let i++
            done
            echo ""

done

29 Fare in modo che tutte le volte che viene eseguito il comando rm, gli elementi dati come argomenti al comando non siano cancellati ma siano spostati nel cestino. Nel caso di precedente esistenza nel cestino di elementi con lo stesso nome di quelli cancellati, il nome di questi ultimi sia modificato con l'aggiunta di un'indicazione temporale.
Suggerimenti: 1) nella messa a punto del comando usare cp invece di rm; 2) usare una funzione.

#!/bin/bash
function CANCELLA {
     trap "rm $i" EXIT
     return
}
for i in $@; do
     CANCELLA
     cestino=$HOME/.Trash/$i
     if [ ! -e $cestino ]
     then
          mv "$i" "date-$i"
     else     
          mv $i -t $HOME/.Trash/
     fi
done

30 Scrivere uno script che restituisca il numero di file regolari contenuti in una directory passata  come parametro contando una sola volta gli elementi di directory che puntano allo stesso inode.

find . -type f -print0 | xargs -0 stat -f %i | sort | uniq | wc –l

30 Creare uno script che prenda come argomenti un PID e un valore percentuale C.
Con l'opzione -k lo script deve interrompere definitivamente il processo di pid PID quando supera la percentuale C di utilizzo della cpu.
Con l'opzione -s (ed il valore S come argomento dell'opzione) deve interrompere il processo di pid PID tutte le volte che supera la percentuale C di utilizzo della cpu e poi farlo riprendere dopo S secondi.

echo " $(ps -p 6221 -o %cpu | tail -1) * 10 " | bc

31 Scrivere uno script bash, da lanciare in background, che avverta l'utente quando in una pagina web, il cui URL Ë passato allo script come primo parametro, si trova una parola passata allo script come secondo parametro. (Suggerimento: usare curl - http://curl.haxx.se/docs/manual.html)

#!/bin/bash
a=1
finded=$(curl "$1" | grep -o -i "$2" | wc -l)
if [ $finded -ge $a ]
then
            echo "Stringa trovata 1 o più volte!"
fi

32 Creare uno script che consenta, ogni volta che Ë eseguito su di una macchina, di ottenere 5 indici utili ad una valutazione approssimata delle seguenti grandezze:
1) Velocit‡ della scrittura su disco
2) Velocit‡ della lettura da disco
3) Velocit‡ di calcolo
4) Velocit‡ di scrittura in RAM
5) Velocit‡ di lettura da RAM

Suggerimento: si ricorda che l'utilizzo dello standard error del built-in time Ë reso pi˘
agevole dalla sua esecuzione in un subshell (tramite il costrutto "()").

#!/bin/bash
echo "TEST DI SCRITTURA!"
echo "ZEROS DATA:"
dd if=/dev/zero of=testfile0 bs=8k count=10000; sync;
echo "RANDOM DATA:"
dd if=/dev/urandom of=testfileR bs=8k count=10000; sync;
echo "TEST DI LETTURA!"
echo "ZEROS DATA:"
dd if=testfile0 of=/dev/null
echo "RANDOM DATA:"
dd if=testfileR of=/dev/null

33 Creare uno script al quale sono passati tre parametri A, B e C e che, lanciato in background:

1) avverta con tre suoni del fatto che il round-trip time dei pacchetti di echo diretti ad A
oltrepassa in media il valore B;

2) avverta con 10 suoni quando la percentuale di pacchetti di echo non ritornati tra quelli
inviati ad A oltrepassa in media il valore C.

Suggerimento: usare il comando ping.

#!/bin/bash
dieci=10
tre=3
echo "Premere CTRL+C per uscire dallo script!"
while :
do
            dieci=10
            tre=3
            ping -c 3 -n $1 | tail -2 | head -1 > elenco.txt
            chmod 755 elenco.txt
            a=$( cut -f 10 -d " " elenco.txt)
            b=$( cut -f 6 -d " " elenco.txt | tr -d '%')
            echo ${a%m*s} > elnum.txt
            chmod 755 elnum.txt
            numero=$(head -1 elnum.txt)
            echo $numero/3 | bc -l > nuovoel.txt
            chmod 755 nuovoel.txt
            narr=$(head -1 nuovoel.txt | awk '{printf("%.0f\n", $1)}')
            if [ "$2" -le "$narr" ]
            then
                       i=1
                       while [ "$i" -le "$tre" ]
                       do
                                   echo -e "\a"
                                   let i++
                       done
            fi
            if [ "$3" -le "$b" ]
            then
                       k=1
                       while [ "$k" -le "$dieci" ]
                       do
                                   echo -e "\a"
                                   let k++
                       done
            fi
done

34 Creare uno script al quale sono passati tre parametri A, B e C e che:

1) Cambi in C l'estensione di tutti i file che hanno estensione B presenti nella directory A 
(es. file1.B in file1.C, file2.B in file2.C, ecc.);
2) Dia un resoconto di tutti i file di cui ha cambiato il nome

#!/bin/bash
cd
percorso=$(find -iname $1)
echo "$percorso"
cd $percorso
x=0; for i in *.$2; do let x++; mv -v $i $(printf "$2%03x.$3" $x); done

34 Creare uno script che produca un output equivalente a quello del comando "top"
(senza utilizzare quest'ultimo) e che si limiti a mostrare per ogni processo esclusivamente
il nome del proprietario, il pid e la percentuale di %cpu utilizzata.

#!/bin/bash
ps -aux | awk '{print $1" "$2" "$3}'

35 Creare uno script - al quale viene passato un parametro N (numero intero positivo) -
che crei nella cartella corrente N soft link agli N file di maggiori dimensioni presenti nel
file system.
Il nome di tali link deve essere costituito da 12 cifre che esprimano la dimensione del file in bytes seguite da un trattino e dal basename originale del file (es. se un file di nome pippo.txt e dimensioni 10 MB rientra tra gli N pi˘ grandi presenti nel file system, deve essere creato un link di nome 000010485760-pippo.txt).

#!/bin/bash
cd
find -type f -exec du -sb {} \;  > elenco.txt
chmod 755 elenco.txt
sort -n -r -k 1 elenco.txt > elenco1.txt
chmod 755 elenco1.txt
percorsosoft=$(find -iname "esame35")
echo "$percorsosoft"
i=1
while [ "$i" -le "$1" ]
do
            files=$(head -$i elenco1.txt | tail -1 | awk '{print $2}')
            echo "$files"
            stat -c%12s $files | tr ' ' '0'
            echo "$dimensione"
            nome=$(echo "${files##.*/}")
            echo "$nome"
            ln -s $files $percorsosoft/$dimensione-$nome
            let i++
done
36 Creare uno script che, utilizzando l'header HTTP Last-Modified, tenga sotto continua osservazione una lista di siti web specificata in un file, e apra in un browser web quelli che rileva essere stati modificati rispetto ad una rilevazione di riferimento.
(Suggerimento: usare curl - http://curl.haxx.se/docs/manual.html)    

#!/bin/bash
conta=$(wc -l elenco.txt | awk '{print $1}')
i=1
while [ $i -le $conta ]
do
            sito=$(head -$i elenco.txt | tail -1 | awk '{print $1}')
            echo "+++$sito"
            curl -b headers http://$sito > ril-$sito.txt
            let i++
done
while :
do
            sleep 5
            k=1
            while [ $k -le $conta ]
            do                  
                       sito=$(head -$k elenco.txt | tail -1 | awk '{print $1}')
                       curl -b headers http://$sito > $sito.txt
                       stringa=$(diff $sito.txt ril-$sito.txt)
                       if [ ! -z "$stringa" ]
                       then
                                   echo "Il sito modificato è $sito!"
                       else
                                   echo "Il sito $sito non è stato modificato!"
                       fi
            let k++
            done
done

36 Si consideri un metodo di autenticazione cosÏ costituito:
la password viene passata all'algoritmo md5 e memorizzata. Quando l'utente inserisce la password
tentativa, questa viene trasformata mediante l'algoritmo md5 e il risultato viene confrontato con
quello memorizzato. La password viene considerata valida se i due risultati coincidono.
Si scriva uno script che utilizzi un metodo brute force ed il dizionario /usr/share/dict/words
per scoprire una password di cui si possegga la codifica md5.

#!/bin/bash
password=dog
md5pass=$(echo $password | md5sum)
cat /usr/share/dict/words > elencoparole.txt
np=$(cat /usr/share/dict/words | wc -l)
k=1
while [ "$k" -le "$np" ]
do      
            parolacercata=$(head -$k elencoparole.txt | tail -1)
            md5cercato=$(echo $parolacercata | md5sum)
            if [ "$md5cercato" == "$md5pass" ]
            then
                       echo "La password scoperta è $parolacercata!"
                       break
            fi
let k++
done

37 Creare uno script da lanciare con la linea di comando:

./weightps N S

con N ed S numeri interi positivi, che fornisca pid e basename degli eseguibili corrispondenti
agli N processi che negli ultimi S secondi hanno utilizzato maggiormente la cpu.

#!/bin/bash
while [ $SECONDS -le $2 ]
do
            ps -eo pcpu,user,pid | sed '1d' |  sort -n -r -k  1 > elenco.txt
done
echo " CPU USER      PID"
i=1
while [ $i -le $1 ]
do
            riga=$(head -$i elenco.txt | tail -1)
            echo "$riga"
            let i++
done

38 Creare uno uno script che a partire dal momento in cui Ë lanciato registri in un file
tutti gli avvii e le terminazioni di processi con il seguente formato:

<istante di avvio> <pid1> <nome eseguibile1> avviato
<istante di avvio> <pid2> <nome eseguibile2> avviato
<istante di terminazione> <pid2> <nome eseguibile2> terminato
<istante di terminazione> <pid1> <nome eseguibile1> terminato
ecc. ecc.

#!/bin/bash
ps axo start_time,pid,cmd | sed '1d' > listaprocessi.txt
cont=$(wc -l listaprocessi.txt | awk '{print $1}')
i=1
while [ $i -le $cont ]
do
            avvio=$(head -$i listaprocessi.txt | tail -1 | awk '{print $1}')
            pid=$(head -$i listaprocessi.txt | tail -1 | awk '{print $2}')
            nome=$(head -$i listaprocessi.txt | tail -1 | awk '{print $3}')
            echo "<$avvio> <$pid> <$nome> avviato"
            let i++
done

39 Creare uno uno script che utilizzando un qualsiasi dizionario ad esso fornito come parametro (es. /usr/share/dict/words) stampi a terminale tutte le coppie palindrome di parole che Ë possibile costruire usando le parole del dizionario (es. "a da").
Suggerimento: per velocizzare le operazioni di test e debugging dello script conviene usare uno pseudo-dizionario di poche righe costruito ad hoc.

#!/bin/bash
cat /usr/share/dict/words > elencoparole.txt
np=$(cat /usr/share/dict/words | wc -l)
k=1
while [ "$k" -le "$np" ]
do      
            parola=$(head -$k elencoparole.txt | tail -1 |tr '[:lower:]' '[:upper:]')
            inversa=$(echo "$parola" | rev)
            if [ $parola == $inversa ]
            then
                       echo "La parola $parola è palindroma!"
            fi
            let k++
done

39 Scrivere una linea di comando che sia in grado di stampare a terminale le lunghezze in righe e i nomi di tutti e soli gli script Bourne shell o bash presenti nella directory /etc.

#!/bin/bash
find /etc -iname "*.sh" > nuovo.txt
chmod 755 nuovo.txt
cont=$(wc -l nuovo.txt | awk '{print $1}')
i=1
while [ $i -le $cont ]
do
            nomescript=$(head -$i nuovo.txt | tail -1)
            nome=$(echo ${nomescript##/*/})
            lunghezza=$(echo ${#nome})
            echo "Il nome dello script è $nome e la sua lunghezza è $lunghezza!"
            let i++
done

40 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.

Suggerimento: per velocizzare le operazioni di test e debugging dello script conviene limitarne l'azione ad una particolare directory e ad un range di inodes (dopo essersi assicurati che tale range abbia qualche elemento all'interno della directory)

#!/bin/bash
cd /home/administrator
find -type d > cartelle.txt
sed -i '1d' cartelle.txt
contcartelle=$(wc -l cartelle.txt | awk '{print $1}')
ls -li > inode.txt
sed -i '1d' inode.txt
continode=$(wc -l inode.txt | awk '{print $1}')
k=1
while [ $k -le $continode ]
do
            inode=$(head -$k inode.txt | tail -1 | awk '{print $1}')
            a=$(find -inum $inode | wc -l)
            if [ $a -gt 1 ]
            then
                       echo "$inode x"
            else
                       echo "$inode ."
            fi
            let k++
done
i=1
while [ $i -le $contcartelle ]
do
            cartella=$(head -$i cartelle.txt | tail -1)
            nuovacartella=$(echo ${cartella:2})
            cd /home/administrator/$nuovacartella
            ls -li > inode.txt
            sed -i '1d' inode.txt
            continode1=$(wc -l inode.txt | awk '{print $1}')
            j=1
            while [ $j -le $continode1 ]
            do
                       inode1=$(head -$j inode.txt | tail -1 | awk '{print $1}')
                       b=$(find -inum $inode1 | wc -l)
                       if [ $b -gt 1 ]
                       then
                                   echo "$inode1 x"
                       else
                                   echo "$inode1 ."
                       fi
                       let j++
            done
            cd
            let i++
done
41 Costruire uno script che prenda come unico parametro il nome di una directory <nome directory>
localizzata all'interno della propria home.
Nell'ipotesi che la struttura e i nomi delle directory contenute nella directory <nome directory>
non cambino, tale script deve essere in grado di effettuare ad ogni ora un backup della cartella
<nome directory> col seguente criterio:

1) Al solo scopo di semplificare lo script, i backup possono essere localizzati nello stesso volume
della directory originaria;
2) le cartelle di ciascun backup orario devono trovarsi all'interno di una directory chiamata
backup-<nome directory> e devono contenere nel nome l'orario del backup
(es. 200905071015-<nome directory>, 200905071115-<nome directory> ecc.);
3) Il primo back-up deve consistere in una copia (effettuata col comando cp) della cartella
originaria;
4) per i back-up seguenti: se i file  contenuti nelle varie cartelle non  hanno subito alcun
cambiamento rispetto all'ultimo backup (di nome, nel contenuto dei dati o dell'inode) sono
semplicemente replicati creando un nuovo hard link al file corrispondente nel precedente backup;
5) se invece i file contenuti nelle varie cartelle hanno subito qualche cambiamento rispetto
all'ultimo backup (di nome, nel contenuto dei dati o dell'inode) o sono stati creati ex-novo,
allora devono essere effettivamente copiati nel backup, nella stessa posizione che hanno
nella cartella di cui si effettua il backup.

#!/bin/bash
pwd > percorso.txt
percorso=$(head -1 percorso.txt)
a=1
i=1
while :
do
            while [ $i -ge 1 ]
            do      
                       if [ $i -eq 1 ]
                       then
                                   data=$(date +%Y%m%d%H%M)
                                   ultimo=$data
                                   cp -r $percorso/$1 $percorso/$data-$1
                                   chmod 777 $percorso/$data-$1
                                   find $percorso/$ultimo-$1 -type d > cartelle.txt
                                   find $percorso/$ultimo-$1 -type f > files.txt
                                   find $percorso/$ultimo-$1 -type f -exec ls -li {} \; > inode.txt
                       fi
                       if [ $i -gt 1 ]
                       then
                                   data2=$(date +%Y%m%d%H%M)
                                   find $percorso/$ultimo-$1 -type d > cartelle1.txt
                                   find $percorso/$ultimo-$1 -type f > files1.txt
                                   find $percorso/$ultimo-$1 -type f -exec ls -li {} \; > inode1.txt
                                   primo=$(diff cartelle.txt cartelle1.txt)
                                   secondo=$(diff files.txt files1.txt)
                                   terzo=$(diff inode.txt inode1.txt)
                                   tot=$primo$secondo$terzo
                                   if [ -z "$tot" ]
                                   then
                                               ln -s $percorso/$ultimo-$1 $percorso/hl$ultimo-$1                                       
                                   else
                                               ultimo=$data2
                                               cp -r $1 $percorso/$data2-$1
                                               find $percorso/$ultimo-$1 -type d > cartelle.txt
                                               find $percorso/$ultimo-$1 -type f > files.txt
                                               find $percorso/$ultimo-$1 -type f -exec ls -li {} \; > inode.txt
                                   fi                                
                       fi
                       sleep 3600
                       let i++
            done
done

42 Costruire due script script1.sh e script2.sh che lavorino in maniera alternata senza mai fermarsi.
Ovvero, quando il primo svolge un'operazione il secondo attende fermo.
Non appena il primo si ferma il secondo comincia a lavorare.
Appena il secondo termina la sua operazione riparte il primo e cosÏ via all'infinito.
Scegliere qualsiasi coppia di operazioni che abbia senso (per es. la scrittura in un file da parte del primo e l'analisi del suo contenuto da parte del secondo).

#!/bin/bash
echo "Ciao"
(sleep 1 && ./esercizio2.sh)

#!/bin/bash
echo "A tutti"
(sleep 1 && ./esercizio1.sh)

43 Scrivere uno script bash che cerchi tutti i files il cui nome contiene caratteri diversi da lettere o cifre e, per ciascun file trovato, proponga all'utente la sostituzione di ciascuno di tali caratteri con un carattere proposto dall'utente.

#!/bin/bash
find -type f > file.txt
cont=$(wc -l file.txt | awk '{print $1}')
i=1
while [ $i -le $cont ]
do
            nome=$(head -$i file.txt | tail -1)
            stringa=$(echo ${nome:1})
            lung=$(echo ${#stringa})
            suffisso=$(echo ${stringa##/*.})
            lung1=$(echo ${#suffisso})
            nlung=$(expr $lung - $lung1)
            stringa1=$(echo ${stringa:1})
            nlung=$(expr $nlung - 2)
            k=0
            while [ $k -lt $nlung ]
            do
                       car=$(echo ${stringa1:$k:1})
                       if [ "$car" == "." ] || [ "$car" == "|" ] || [ "$car" == "!" ] || [ "$car" == "£" ] || [ "$car" == "$" ] || [ "$car" == "%" ] || [ "$car" == "&" ] || [ "$car" == "/" ] || [ "$car" == "=" ] || [ "$car" == "?" ] || [ "$car" == "^" ] || [ "$car" == "°" ] || [ "$car" == "-" ] || [ "$car" == "_" ]
                       then
                                   echo "Inserire carattere da sostituire:"                           
                                   read nuovocar
                                   echo "$nuovocar" | tr -d "\n" >> stringhe.txt
                       else
                                   echo "$car" | tr -d "\n" >> stringhe.txt
                       fi
            let k++
            done
            nuovonome=$(head -1 stringhe.txt)
            rm stringhe.txt
            nometot=$nuovonome.$suffisso
            echo "$nometot"
let i++
done
#Per semplicità ho eseguito lo script nella cartella esame43, se volessimo effettuare un controllo su tutti i file presenti nel pc basterebbe inserire il percorso in find e successivamente effettuando diverse operazioni e togliendo il percorso di ogni file avremmo la lista di tutti i file senza percorso, infine rimuovendo e conteggiando le diverse lunghezze delle stringhe escludendo i suffissi possiamo procedere alla sostituzione dei caratteri speciali.

44 Scrivere uno script bash che abbia lo stesso funzionamento del comando cp ma conservi la data di modifica del file originario nel file di destinazione.

#!/bin/bash
echo "1. File testo, sh, tmp"
echo "2. Cartella"
echo "3. File gz"
read scelta
case $scelta in
    1)
            echo "Inserire nome file o cartella da copiare:"
            read nome
        if [ $nome == *.txt ] || [ $nome == *.tmp ] || [ $nome == *.sh ]
            then
            echo "Inserire percorso dove copiare il file:"
            read percorso
            cat $nome > $percorso/$nome
            touch -m -r $nome $percorso/$nome
            fi
    ;;
    2)
            echo "Inserire nome file o cartella da copiare:"
            read nome
        echo "Inserire percorso dove copiare la cartella:"
            read percorso
            mkdir $percorso/$nome
            ls -l $nome | awk '{print $9}' | sed '1d' > lista.txt
            cont=$(wc -l lista.txt | awk '{print $1}')
            i=1
            while [ $i -le $cont ]
            do
                       nome2=$(head -$i lista.txt | tail -1)
                       if [ $nome2 == *.txt ] || [ $nome2 == *.tmp ] || [ $nome2 == *.sh ]
                       then
                                   cat $nome/$nome2 > $percorso/$nome/$nome2
                                   touch -m -r $nome/$nome2 $percorso/$nome/$nome2
                                   let i++
                       fi
                       if [ $nome2 == *.gz ]
                       then
                                   gunzip $nome2
                                   nome3=$(echo ${nome2%.*z})
                                   cat $nome/$nome3 > $percorso/$nome/$nome3
                                   touch -m -r $nome/$nome3 $percorso/$nome/$nome3
                                   gzip $percorso/$nome/$nome3
                                   gzip $nome/$nome3
                                   touch -m -r $nome/$nome2 $percorso/$nome/$nome3
                                   let i++
                       fi
            done
    ;;
    3)
            echo "Inserire nome file o cartella da copiare:"
            read nome
        if [ $nome == *.gz ]
            then
            gunzip $nome
            nome1=$(echo ${nome%.*z})
            echo "Inserire percorso dove copiare il file:"
            read percorso
            cat $nome1 > $percorso/$nome1
            touch -m -r $nome1 $percorso/$nome1
            gzip $percorso/$nome1
            gzip $nome1
            touch -m -r $nome $percorso/$nome
            fi        
    ;;
esac

45 Creare uno script che produca un log che registri tutti i processi lanciati dall'avvio dello
script con l'indicazione di quale Ë il parent che li ha lanciati

pid=(­`ps axo pid)
ppid=(`ps axo ppid`)
echo “Il processo ${ppid[$i]} ha lanciato il processo ${pid[$i]}” > log.txt

45 Trasformare ricorsivamente tutti i nomi di file contenuti in una directory sostituendo
i caratteri maiuscoli con i minuscoli.

for file in *
do
            fnome=`basename $file`
            n=ècho $fnome | tr a-z A-Z`
            echo $n
            if [“$fnome” != “$n” ]
then
            mv $fnome $n
fi
done
exit $?

45 Creare uno script che aggiorni continuamente l'ora completa dei secondi

While :
do
            date
            sleep 1
done

46 Fare in modo che il proprio prompt principale indichi il numero di utenti che hanno almeno una sessione interattiva aperta nel sistema

#!/bin/bash
ps aux | sed '1d' | sort -n -r -k 3 | head -1

47 Supporre di avere in un file una lista di alcuni file eseguibili sulla propria macchina, insieme
con i loro digest md5. Il file potrebbe avere il seguente formato:

/usr/bin/cat  <TAB> 0039cd507d558781869e1b6b861d7d9e
/usr/bin/find <TAB> af07b42f06eb72336317a1d23c7c4557
ecc.

Si realizzi uno script che, eseguito in background, consideri periodicamente i processi
originati da un eseguibile il cui nome Ë presente nel file suddetto.
Per tali eseguibili si verifichi che il digest md5 sia uguale a quello indicato nel file.
In caso contrario, lo script riporti i dati rilevanti in un file di log e, in presenza
di un'opzione -d sulla linea di comando, interrompa i processi per cui Ë stata
rilevata la differenza.
#!/bin/bash
while :
do
            sleep 5
            conto=$(wc -l elenco.txt | awk '{print $1}')
            echo "$conto"
            i=1
            while [ $i -le $conto ]
            do
                       processo=$(awk '{print $1}' elenco.txt | head -$i | tail -1)
                       codice=$(ps aux | grep $processo | grep ?? | awk '{print $11}' | md5)
                       codiceoriginale=$(awk '{print $3}' elenco.txt | head -$i | tail -1)
                       if [ "$codice" == "$codiceoriginale" ]
                       then
                                   echo "Digest md5 del processo $processo uguale!"                  
                       else
                                   if [ "$codice" == "d41d8cd98f00b204e9800998ecf8427e" ]
                                   then
                                               echo "Processo già killato!"
                                   else
                                               diff -a $codice $codiceoriginale
                                               echo "Il processo $processo con digest md5 originale $codiceoriginale cambiato in $codice" >> log.txt
                                               pid=$(ps aux | grep $processo | awk '{print $2}')
                                               kill $pid
                                   fi
                       fi
            let i++
            done
done
                      
48 Scrivere uno script che richieda una password all'utente e che possa verificarne l'esattezza solo tramite l'inserimento di una chiavetta USB ("pendrive") nel computer.
La chiavetta non deve contenere in alcun modo la password leggibile in chiaro.

#!/bin/bash
while :
do
            echo "Inserire la password:"
            read password
            passmd=$(md5 -s $password | awk '{print $4}')
            nome=$(ls -l /Volumes | grep staff | awk '{print $9}')
            percorso=/Volumes/$nome
            cd $percorso
            password=$(cat password.txt | head -1)
            if [ "$passmd" == "$password" ]
            then
                       echo "La password inserita è corretta!"
                       break
            else
                       echo "Password sbagliata!"
            fi
done  

48 Scrivere uno script che calcoli il totale della memoria fisica utilizzata dai processi in esecuzione nel sistema all'istante del lancio e ne valuti il valore percentuale rispetto alla quantit‡ di RAM installata nel sistema.

#!/bin/bash
ps -eo %mem | sed '1d' > elenco.txt
cont=$(awk '{ SUM += $1} END { print SUM }'  elenco.txt)
echo "La percentuale di memoria totale usata è $cont!"
echo "ATTENDERE....."
system_profiler |  grep -A 9 "BANK [0-9]/DIMM[0-9]" | grep Size > ram.txt
a=$(system_profiler |  grep -A 9 "BANK [0-9]/DIMM[0-9]" | grep Size | wc -l)
i=1
ramtot=0
while [ $i -le $a ]
do
            ram=$(head -$i ram.txt | tail -1 | awk '{print $2}')
            ramtot=$(($ramtot+$ram))
            let i++
done
ramtk=$(($ramtot*1024*1024))
echo "La ram totale in kilobyte è $ramtk!"
echo "I kilobyte di ram usata sono:"
echo 'scale=1; '$ramtk' * '$cont' / 100' | bc

49 Un minorenne trascorre troppo tempo giocando con due computer games. Siamo vicini alla fine dell'anno scolastico e volete in questo periodo limitare questo comportamento facendo in modo che, a tre minuti dall'avvio di ciascuno di tali programmi, la loro esecuzione sia interrotta senza cheil ragazzo si renda conto del motivo.
Predisporre uno script (che qualcun altro inserir‡ tra i login items) che svolga la funzione richiesta.

[Suggerimento: a scopo di test, immaginare che i due giochi siano due qualsiasi altri programmi
presenti sul computer sul quale si prepara lo script]

#!/bin/bash
while :
do
            pid1=$(ps aux | grep Contacts | grep Applications | awk '{print $2}')
            pid2=$(ps aux | grep Notes | grep Applications | awk '{print $2}')
            if [ ! -z $pid1 ]
            then
                       i=0
                       while [ $i -le 180 ]
                       do
                                   sleep 1
                                   if [ $i -eq 180 ]
                                   then
                                               kill $pid1
                                   fi
                       let i++
                       done
            fi
            if [ ! -z $pid2 ]
            then
                       k=0
                       while [ $k -le 180 ]
                       do
                                   sleep 1
                                   if [ $k -eq 180 ]
                                   then
                                               kill $pid2
                                   fi
                       let k++
                       done
            fi
done

50 Senza utilizzare il comando diff, si scriva uno script bash che si comporti come il comando "diff -r" quando gli argomenti forniti siano due directory.

find $percorso2 -type f > file2.txt
a2=$(wc -l file2.txt | awk '{print $1}')
i1=1
while [ $i1 -le $a1 ]
do
            file1=$(head -$i1 file1.txt | tail -1)
            st1=$(echo ${file1##.*/})
            diversi=$(grep "$st1" file2.txt)
            if [ -z $diversi ]
            then
                       echo "***Il file $file1 non esiste nella $cartella2!***"
                       cat $file1
            else
                       echo "***Il file $file1 esiste nella $cartella2!***"
                       cfile1=$(cat $file1 | wc -l)
                       cont1=1
                       while [ $cont1 -le $cfile1 ]
                       do
                                   riga1=$(head -$cont1 $percorso1/$st1| tail -1)
                                   riga2=$(head -$cont1 $percorso2/$st1| tail -1)
                                   if [ "$riga1" != "$riga2" ]
                                   then
                                               echo "Differenza alla riga $cont1 per i file $file1 nelle due cartelle!"
                                               echo ">$riga1"
                                               echo "<$riga2"
                                   fi
                       let cont1++
                       done
            fi
let i1++
done
#
#
#
i2=1
while [ $i2 -le $a2 ]
do
            file2=$(head -$i2 file2.txt | tail -1)
            st2=$(echo ${file2##.*/})
            diversi=$(grep "$st2" file1.txt)
            if [ -z $diversi ]
            then
                       echo "***Il file $file2 non esiste nella $cartella1!***"
                       cat $file2
            else
                       echo "***Il file $file2 esiste nella $cartella1!***"
                       cfile2=$(cat $file2 | wc -l)
                       cont2=1
                       while [ $cont2 -le $cfile2 ]
                       do
                                   riga1=$(head -$cont2 $percorso2/$st2| tail -1)
                                   riga2=$(head -$cont2 $percorso1/$st2| tail -1)
                                   if [ "$riga1" != "$riga2" ]
                                   then
                                               echo "Differenza alla riga $cont2 per i file $file2 nelle due cartelle!"
                                               echo ">$riga1"
                                               echo "<$riga2"
                                   fi
                       let cont2++
                       done
            fi
let i2++
done
#
#
#


find $percorso1 -type d > cartella1.txt
b1=$(wc -l cartella1.txt | awk '{print $1}')
find $percorso2 -type d > cartella2.txt
b2=$(wc -l cartella2.txt | awk '{print $1}')
k1=1
while [ $k1 -le $b1 ]
do
            cart1=$(head -$k1 cartella1.txt | tail -1)
            sc1=$(echo ${cart1##.*/})
            cdiverse=$(grep "$sc1" cartella2.txt)
            if [ -z $cdiverse ]
            then
                       echo "***La cartella $cart1 non esiste nella $cartella2!***"
            else
                       echo "***La cartella $cart1 esiste nella $cartella2!***"
            fi
let k1++
done
#
#
#
find $percorso1 -type d > cartella1.txt
b1=$(wc -l cartella1.txt | awk '{print $1}')
find $percorso2 -type d > cartella2.txt
b2=$(wc -l cartella2.txt | awk '{print $1}')
k2=1
while [ $k2 -le $b2 ]
do
            cart2=$(head -$k2 cartella2.txt | tail -1)
            sc2=$(echo ${cart2##.*/})
            cdiverse=$(grep "$sc2" cartella1.txt)
            if [ -z $cdiverse ]
            then
                       echo "***La cartella $cart2 non esiste nella $cartella1!***"
            else
                       echo "***La cartella $cart2 esiste nella $cartella1!***"
            fi
let k2++
done

51 Creare uno script e un soft link ad esso. Fare in modo che a seconda del nome con cui lo (stesso) script viene invocato svolga operazioni differenti.

#!/bin/bash
echo "Invocare lo script:"
read nome
while [ "$nome" != "softlink" ] || [  "$nome" != "esercizio1.sh" ]
do
            if [ "$nome" == "softlink" ]
            then
                       echo "Softlink"
                       break
            fi
            if [ "$nome" == "esercizio1.sh" ]
            then
                       echo "Script"
                       break
            fi
            echo "Nome errato invocare nuovamente lo script:"
            read nome
done

51 Generare in sequenza dei numeri casuali e fermarsi quando esiste un file il cui numero di inodesia uguale all'ultimo numero generato.
Di tale file si stampino tutti i nomi assunti e le directory in cui Ë contenuto.

#!/bin/bash
while :
do
            a1=$((RANDOM%10))
            a2=$((RANDOM%10))
            a3=$((RANDOM%10))
            a4=$((RANDOM%10))
            a5=$((RANDOM%10))
            a6=$((RANDOM%10))
            inode=$a1$a2$a3$a4$a5$a6
            cercato=$(find . -inum $inode)
            if [ ! -z $cercato ]
            then
                       nomefile=$(echo ${cercato##.*/})
                       echo "Il nome del file che ha numero di inode $inode è $nomefile!"
                       echo "Il percorso del file è $cercato!"
                       break
            fi
done

52 Creare una cartella nella propria home su hplinux2.unisalento.it e una cartella sulla propria home Mac OS X e scrivere uno script che ogni ora sincronizzi le due cartelle usando il comando rsync.

#!/bin/bash
while :
do
            rsync -a --delete /Users/danilo/Desktop/SISTEMI-OPERATIVI/ESERCIZI\ SVOLTI/esame52/A /Users/danilo/Desktop/SISTEMI-OPERATIVI/ESERCIZI\ SVOLTI/esame52/B
            sleep 3600
done

53 Usando il comando dd creare un file di contenuto casuale e aggiungere ad esso un blocco alla volta fermandosi quando in esso compare la stringa ASCII "ab".

#!/bin/bash
while :
do
            dd if=/dev/random count=1 >> file.txt
            stringa=$(grep -a "ab" file.txt)
            if [ ! -z "$stringa" ]
            then
                       echo "Trovato!"
                       break
            fi
done

54 Inserire nello script denominato nff.sh, contenuto nella stessa directory del presente testo, le istruzioni necessarie a far disegnare allo standard output un'indicazione grafica (per esempio, una barra di completamento) che, istante per istante, permetta di capire quale percentuale del compito complessivo sia stata gi‡ svolta.

#!/bin/bash
function showBar {
 percDone=$(echo 'scale=2;'$1/$2*100 | bc)
 barLen=$(echo ${percDone%'.00'})
 bar=''
 fills=''
 for (( b=0; b<$barLen; b++ ))
 do
  bar=$bar"="
 done
 blankSpaces=$(echo $((100-$barLen)))
 for (( f=0; f<$blankSpaces; f++ ))
 do
  fills=$fills"_"
 done
 clear
 echo '['$bar'>'$fills'] - '$barLen'%'
}
i=0
while [ $i -le 20 ]
do
            echo "$i"
            let i++
            showBar $i 21
done

55 Scrivere uno script che:
1) individui quali siano i processi lanciati all'avvio del sistema;
2) li stampi nell'ordine in cui sono stati lanciati;
3) li stampi ordinandoli secondo il consumo di CPU che hanno effettuato.

#!/bin/bash
oracompleta=$(ps aux | sed '1d' |  sort -n -k 2 | head -1 | awk '{print $9}')
ora=$(echo ${oracompleta:0:1})
fuso=$(echo ${oracompleta:4})
minuti=$(echo ${oracompleta:2:2})
let "minuti1 = $minuti + 1"
let "minuti2 = $minuti1 + 1"
ps aux | sed '1d' |  sort -n -k 2 | grep "$ora:$minuti$fuso" | grep "??" > elenco.txt
ps aux | sed '1d' |  sort -n -k 2 | grep "$ora:$minuti1$fuso" | grep "??" >> elenco.txt
ps aux | sed '1d' |  sort -n -k 2 | grep "$ora:$minuti2$fuso" | grep "??" >> elenco.txt
echo "I processi lanciati all'avvio del sistema sono:"
cat elenco.txt
ps aux | sed '1d' | grep "$ora:$minuti$fuso" | grep "??" > cpu.txt
ps aux | sed '1d' | grep "$ora:$minuti1$fuso" | grep "??" >> cpu.txt
ps aux | sed '1d' | grep "$ora:$minuti2$fuso" | grep "??" >> cpu.txt
echo "I processi ordinati secondo la CPU sono:"
sort -n -k 3 | cat cpu.txt

56 Creare uno script che, utilizzando l'header HTTP Last-Modifiedtenga sotto continua osservazione un sito web specificato sulla linea di comando, e lo apra in un browser web quando risulta modificato rispetto ad una rilevazione di riferimento.
(Suggerimento: usare curl - http://curl.haxx.se/docs/manual.html)

Esercizio già dato in precedenza.

56 Di una password si possiede il digest 0b74bb1d4ec4e8714b6b60685302d21eea3e9afd .
Si sospetta anche che tale password possa essere una parola della lingua inglese.
Si scriva uno script che, usando un metodo brute force ed il dizionario /usr/share/dict/words, scopra
il metodo scelto per il digest e la password. [Suggerimento: usare il comando openssl dgst]

#!/bin/bash
cat /usr/share/dict/words > elenco.txt
a=$(wc -l elenco.txt | awk '{print $1}')
i=1
while [ $i -le $a ]
do
            parola=$(head -$i elenco.txt | tail -1)
            head -$i elenco.txt | tail -1 > parola.txt
            codice=$(openssl dgst -md5 parola.txt | awk '{print $2}')
            if [ "$codice" == "0b74bb1d4ec4e8714b6b60685302d21eea3e9afd" ]
            then
                       echo "La password è $parola!"
            fi
let i++
done
           
57 Creare uno script che, con un periodo dato come parametro, verifichi se siano in esecuzione
processi per i quali l'effective ID sia diverso dal real ID.
[Suggerimento: provare lo script utilizzando il programma passwd]

#!/bin/bash
while :
do
            ps -e -opid,ruid,uid,comm > elenco.txt
            cont=$(wc -l elenco.txt | awk '{print $1}')
            i=1
            while [ $i -le $cont ]
            do
                       ruid=$(head -$i elenco.txt | tail -1 | awk '{print $2}')
                       euid=$(head -$i elenco.txt | tail -1 | awk '{print $3}')
                       processo=$(head -$i elenco.txt | tail -1 | awk '{print $4}')
                       if [ $ruid != $euid ]
                       then
                                   echo "Il realuserid è diverso dall'effectiveid per il processo $processo!"
                       fi
            let i++
            done
            echo "PER USCIRE DALLO SCRIPT PREMERE CTRL + C!"
            sleep $1
done

57 Un sistema di backup dei dati contenuti in una directory agisce nel seguente modo:
1) al primo backup crea una copia della directory originale.
2) in ciascuno dei backup che compie periodicamente in seguito, crea una ulteriore directory copia della directory originale, nella quale:
a) dei file non modificati, per contenuto e per posizione, rispetto alla prima copia, fa un hard link alla versione del primo backup;
b) degli altri fa una copia nella stessa posizione che hanno nella directory originale.
Scrivere uno script che, prese come argomento due versioni del backup, evidenzi quali sono i file effettivamente copiati nella pi˘ recente (invece che semplicemente hard linked).

#!/bin/bash
find ./$1 -type f -exec ls -li {} \; > elenco1.txt
find ./$2 -type f -exec ls -li {} \; > elenco2.txt
conta1=$(wc -l elenco1.txt | awk '{print $1}')
conta2=$(wc -l elenco2.txt | awk '{print $1}')
i=1
while [ $i -le $conta2 ]
do
            percorso=$(head -$i elenco2.txt | tail -1 | awk '{print $10}')
                       inode=$(head -$i elenco2.txt | tail -1 | awk '{print $1}')
                       inodecercato=$(grep $inode elenco1.txt)
                       if [ -z "$inodecercato" ]
                       then
                                   echo "Il file $percorso è un file copiato!"
                       fi
let i++
done

58 Creare uno script che individui tutte le librerie dinamiche caricate in memoria dai processi
in esecuzione nel sistema al momento del suo lancio e, per ciascuna di esse, indichi da quanti
processi sia utilizzata.

#!/bin/bash
ora=$(ps aux | sed '1d' | sort -n -r -k 2 | tail -1 | awk '{print $9}')
ps aux | grep Library | grep ?? | grep $ora > elenco.txt
cont=$(wc -l elenco.txt | awk '{print $1}')
i=1
while [ $i -le $cont ]
do
            processo=$(head -$i elenco.txt | tail -1 | awk '{print $2}')
            libreria=$(head -$i elenco.txt | tail -1 | awk '{print $11}')
            stringa=$(lsof -p $processo )
            if [ -z "$stringa" ]
            then
                       echo "Per il processso che utilizza la libreria $libreria i processi utilizzati sono 1!"
            else
                       a=$(lsof -p $processo | sed '1d' | wc -l)
                       echo "Per il processo che utilizza la libreria $libreria i processi utilizzati sono $a!"
            fi
let i++
done

58 Creare uno script che trasformi la codifica di un file di testo da UTF-8 a ISO_8859-1

#!/bin/bash
iconv -f UTF-8 -t ISO_8859-1 testo.txt

59 Avete montato nel vostro computer un volume esterno (PenDrive, CD, DVD, HD etc.) e quando date il comando per espellerlo ricevete il messaggio "Impossibile espellere il volume perché utilizzato da un'applicazione".
Creare uno script che, dopo aver elencato le applicazioni che utilizzano il volume, ne interrompa l'esecuzione dopo avervi chiesto il permesso di farlo.

#!/bin/bash
usb=$(ls -li /Volumes | sed '1d' | head -1 | awk '{print $10}')
lsof | grep $usb > elenco.txt
cont=$(wc -l elenco.txt | awk '{print $1}')
echo "Le applicazioni che utilizzano i processi sono le seguenti:"
i=1
while [ $i -le $cont ]
do
            applicazione=$(head -$i elenco.txt | tail -1 | awk '{print $9}')
            echo "$applicazione"
            let i++
done
echo "Siete sicuri di voler interrompere i seguenti processi per poter togliere la chiavetta (rispondere SI oppure NO):"
read risposta
if [ "$risposta" == "SI" ]
then
            k=1
            while [ $k -le $cont ]
            do
                       pid=$(head -$k elenco.txt | awk '{print $2}')
                       kill -9 $pid
                       let k++
            done
            echo "Ora potete togliere la chiavetta!"
else
            echo "Sarà impossibile togliere la chiavetta chiudere prima i processi che la utilizzano!"
fi

59 Progettare un metodo che permetta ad un(a) vostro/a amico/a con il quale condividete una password segreta e che riceva un vostro file in chiaro, di essere certo che il file è effettivamente stato scritto da voi e non è stato modificato da alcuno. Implementare il metodo in uno script che eventualmente passerete al(la) vostro/a amico/a perché lo possa eseguire al momento opportuno.

#!/bin/bash
titolol=$(find . -iname filecriptato.zip)
titoloc=$(echo ${titolol##.*/})
if [ "$titoloc" != "filecriptato.zip" ]
then
            echo "Il file è stato manomesso!"
fi
codicefile=794d732c529bfeb15a8ecb7858f1d551
unzip filecriptato.zip
codiceconferma=$(cat filecrittografato.txt | md5)
if [ $codicefile == $codiceconferma ]
then
            echo "Il file non è stato manomesso!"
            echo "Adesso lo puoi visualizzare!"
else
            echo "Il file è stato manomesso!"
fi

60 Dato un processo A (scelto a caso tra quelli in esecuzione nella macchina sulla quale si lavora), creare uno script che al ricevimento di un certo segnale effettui una misura
dell'occupazione di memoria fisica e di memoria virtuale da parte del processo A e
al ricevimento di un altro segnale effettui una misura della percentuale di CPU utilizzata
dal processo A e di quella totale utilizzata da tutti i processi del sistema.
Le misure devono essere raccolte in due separati file di log (uno per la memoria e l'altro per la CPU) insieme con l'indicazione dell'istante relativo a ciascuna misura.

#!/bin/bash
function primo {
           
            ps aux | sed '1d' | sort -k 1 | grep $pid | grep ?? > elenco0.txt
            tempo=$(date)
            echo "La data di rilevamento è $tempo!" >> log.txt
            memoriav=$(head -1 elenco0.txt | awk '{print $5}')
            echo "La memoria virtuale del processo è $memoriav!" >> log.txt
            memoriaf=$(head -1 elenco0.txt | awk '{print $6}')
            echo "La memoria virtuale del processo è $memoriaf!"  >> log.txt
            echo -n >> log.txt
}

function secondo {

            ps -eo pid,vsize,rss,%cpu,tt | sed '1d' | sort -k 1 | grep $pid | grep ?? > elenco1.txt
            tempo1=$(date)
            echo "La data di rilevamento è $tempo1!" >> log1.txt
            cpup=$(head -1 elenco1.txt | awk '{print $4}')
            echo "La CPU del processo è $cpup!" >> log1.txt
            ps aux | sed '1d'  > elenco2.txt
            echo "La percentuale totale di CPU è:" >> log1.txt
            awk '{ SUM += $3} END { print SUM }'  elenco2.txt >> log1.txt
}
echo "Inserire il pid e poi inviare il segnale CTRL+Z per ottenere mem virtuale e fisica e CTRL+\ per ottenere cpu processo e cpu totale:"
while :
do
            read pid
            trap primo SIGTSTP
            trap secondo SIGQUIT
done

61 Realizzare uno script che periodicamente, in presenza di un file chiamato con il suo stesso nome ad un certo URL*, lo scarichi e, se lo trova differente da se stesso, cessi la propria esecuzione per passare all'esecuzione del file scaricato.

Note:
il tipo di URL può essere scelto a proprio piacimento (file, http, afp etc.) purché funzionante.

#!/bin/bash
curl -o esercizio1.html http://www.diretta.it
while :
do
            curl -o file.html http://www.diretta.it
            stringa=$(diff esercizio1.html file.html)
            if [ ! -z "$stringa" ]
            then
                       emacs file.html && exit
            fi
            sleep 3
done
           
62 Il digest md5 di un file contenente 2 caratteri è e0aa021e21dddbd6d8cecec71e9cf564.
Scrivere uno script che stampi il contenuto del file e indicare il tempo macchina
consumato in modalità utente e in modalità sistema eseguendo tale script.

#!/bin/bash
./esercizio2.sh
lista=$(echo {A..z} {0..9})
for c1 in $lista
do
   for c2 in $lista
   do
      decr=$(echo -n $c1$c2 md5 | rev | cut -c 4- | rev)
      if [ "$decr" == "e0aa021e21dddbd6d8cecec71e9cf" ]
      then        
         echo "Trovato!"
         echo "Le lettere sono : $c1$c2"
      fi
   done
done
exit

#!/bin/bash
echo "Il tempi richiesti sono:"
time (./esercizio1.sh | exit)

63 Scrivere uno script che prenda come argomento il nome di un file e restituisca il
numero di zeri e di uni (cifre binarie) presenti nel file.

#!/bin/bash
cont=$(wc -l $1 | awk '{print $1}')
cont0=0
cont1=0
i=1
while [ $i -le $cont ]
do
            riga=$(head -$i $1 | tail -1)
            lunghezza=$(echo ${#riga})
            while [ $lunghezza -ge 0 ]
            do
                       carattere=$(echo ${riga:$lunghezza:1})
                       if [ "$carattere" == "1" ]
                       then
                                   let cont1++
                       fi
                       if [ "$carattere" == "0" ]
                       then
                                   let cont0++
                       fi
            let lunghezza--
            done
            let i++
done
echo "Il numero di 1 presenti nel file è $cont1!"
echo "Il numero di 0 presenti nel file è $cont0!"

63 Scrivere uno script che rilevi la presenza di siti web nella subnet in cui si trova la macchina su cui viene eseguito e avvisi l'utente qualora la home page di uno qualunque di tali siti contenga una parola passata come parametro.

#!/bin/bash
ifconfig | grep inet | grep -v inet6 | awk '{print $2}' > elenco.txt
a=$(wc -l elenco.txt | awk '{print $1}')
i=1
while [ $i -le $a ]
do
            indirizzo=$(head -$i elenco.txt | tail -1)
            stringa=$(ping -c1 $indirizzo | grep -o -i $1)
            if [ ! -z "$stringa" ]
            then
                       echo "Ho trovato la parola al seguente indirizzo IP $indirizzo!"
            fi
let i++
done

64 Scrivere uno script che stampi a terminale un grafico che abbia l'ascissa in verticale (crescente con il numero di riga nella finestra terminale) e l'ordinata in orizzontale (crescente con il numero di colonna nella finestra terminale) e che rappresenti memoria fisica occupata dal processo cheesegue lo script in funzione della dimensione di un array allocato dallo stesso script.
Determinare in che misura la deallocazione dell'array influisca sull'uso di memoria reale da partedel processo.

#!/bin/bash
pid=$(ps aux | sed '1d' | grep esercizio1.sh | grep /bin/bash | tail -1 | awk '{print $2}')
i=0
while :
do
            sleep 1
            memoria=$(ps aux | grep $pid | awk '{print $6}')
            array[$i]=$memoria
            k=0
            while [ $k -le $memoria ]
            do
                       if [ $k -eq $memoria ]
                       then
                                   echo "x"
                       else
                                   echo -n "|"
                       fi
            let k++
            done
    let i++
done
#Se dealloco l'array e lo stampo come grafico non cambia nulla!

65 Scrivere uno script che effettui un monitoraggio degli accessi ad un certo file e che interrompai processi che tentano di aprirlo se essi non sono stati generati dall'esecuzione di un programma il cui percorso è elencato in un'apposita lista di programmi autorizzati.
[Suggerimento: per poter testare lo script si scelgano file e programmi tali da non richiedere privilegi particolari. Rimane sottinteso che, per poter funzionare con qualunque set di dati,lo script avrà necessità di essere lanciato con il comando sudo]

#!/bin/bash
echo "Premere CTRL+C per uscire!"
while :
do
            lsof | grep $1 > processi.txt
            cont=$(wc -l processi.txt | awk '{print $1}')
            i=1
            while [ $i -le $cont ]
            do
                       programma=$(head -$i processi.txt | tail -1 | awk '{print $1}')
                       pid=$(head -$i processi.txt | tail -1 | awk '{print $2}')
                       stringa=$(grep $programma elenco.txt)
                       if [ -z $stringa ]
                       then
                                   kill $pid
                       fi
            let i++
            done
sleep 3
done
           
66 Senza utilizzare il comando file, scrivere uno script che prenda come argomento il nome di un file che si sa contenere del testo italiano puro (non formattato) e stampi a terminale il nome della codifica con cui il testo è rappresentato.

#!/bin/bash 
FILE=$1 
PATTERN1=UTF-8
PATTERN2=UTF-16 
for enc in $( iconv -l | sed 's/..$//')  
do  
    iconv -f $enc -t UTF-8 $FILE  2>/dev/null | grep $PATTERN1 && echo $enc  
     iconv -f $enc -t UTF-16 $FILE  2>/dev/null | grep $PATTERN2 && echo $enc  
done  

67 Scrivere due script bash che si alternino all'infinito nell'esecuzione stampando ciascuno una propria stringa a terminale. Fare in modo che la semplice pressione del tasto "s" arresti entrambi.

#!/bin/bash
echo "Premere s per uscire o altro per continuare!"
read keypress
echo "Ciao"
if [ "$keypress" == "s" ]
then
            exit
else
            ./esercizio2.sh
fi

#!/bin/bash
echo "Premere s per uscire o altro per continuare!"
read keypress
echo "a tutti!"
if [ "$keypress" == "s" ]
then
            exit
else
            ./esercizio1.sh
fi

67 Si vogliono salvare tutti i propri file su una pendrive ma ci si rende presto conto del fatto che non esistono pendrive di dimensioni sufficienti a salvarli tutti. Allora si decide di salvare solo i file più recenti di un certo numero di anni. Scrivere un script bash che aiuti a capire per ciascuna dimensione di pendrive quanti sono gli anni più recenti che questa può contenere.

#!/bin/bash
somma=0
echo "Inserire dimensione pendrive in byte:"
read dimensione
ls -lT | sort -k 9 -n | sed '1d' > elenco.txt
a=$(wc -l elenco.txt | awk '{print $1}')
i=1
while [ $i -le $a ]
do
            partenza=$(head -1 elenco.txt | awk '{print $9}')
            grandezza=$(head -$i elenco.txt | tail -1 | awk '{print $5}')
            anno=$(head -$i elenco.txt | tail -1 | awk '{print $9}')
            somma=$(echo "$[$grandezza+$somma]")
            if [ "$dimensione" -lt "$somma" ]
            then
                       let anno--
                       if [ "$anno" -lt "$partenza" ]
                       then
                                   echo "Comprare una chiavetta più grande!"
                                   exit
                       else
                                   echo "Puoi copiare i file fino all'anno $anno!"
                                   exit
                       fi
            fi
let i++
done

68 Scrivere uno script bash che, preso come primo argomento un file di tipo immagine (es. JPEG, PNG, etc.), lo modifichi facendolo apparire al comando "file" un eseguibile (di tipo Mach-O su Mac OS X e di tipo ELF su Linux), curando anche che le informazioni necessarie a visualizzare l'immagine siano sempre contenute nel file risultante e facilmente estraibili da esso.
Il nome del file risultante dalla modifica sia passato allo script come secondo argomento.
Provare il funzionamento dello script con un'immagine reale.

#!/bin/bash
percorso=$(pwd)
if [ "$percorso" == "/Users/danilo/Desktop" ]
then
            cp /Users/danilo/Desktop/lago-alpino.jpg /Users/danilo/Desktop/$1.bundle
            file --mime $1.bundle
else
            cp /Users/danilo/Desktop/lago-alpino.jpg /Users/danilo/Desktop/$1.elf
            file --mime $1.bundle
fi

69 Scrivere uno script bash che, preso come primo argomento il nome di un altro script A esistente ed
eseguibile, dia indicazione ad intervalli di un secondo delle seguenti quantità istantanee:
1) numero di processi in esecuzione all'istante della misura generati dal lancio di A;
2) somma delle quantità di memoria reale utilizzate all'istante dai processi in esecuzione generati dal lancio di A;
[per i soli studenti che sostengono l'esame per il corso da 9 CFU:]
3) numero totale dei file aperti dai processi in esecuzione all'istante della misura generati dal lancio di A.

Per il test della propria implementazione utilizzare lo script DoesNothing.sh, contenuto nella stessa directory del presente testo.
#!/bin/bash
while :
do
            sleep 1
            numprocessi=$(ps -ef | grep -v 'grep' | grep -v esercizio1.sh | grep $1 | awk '{print $2}' | wc -l | awk '{print $1}')
            echo "Il numero di processi generati da $1 è $numprocessi!"
            ps aux | grep -v 'grep' | grep -v esercizio1.sh | grep $1 | awk '{print $4}' > memoriareale.txt
            cat memoriareale.txt
            exec 0<memoriareale.txt
            awk '{ somma += $1 } ; END { print "totale della colonna:", somma }'
done
           
70 Scrivere uno script bash che a partire da un indirizzo di un sito web, esplori automaticamente il web per determinare una statistica dei programmi usati per allestire i server web dei siti esplorati (es. Apache, IIS, ecc).

#!/bin/bash
if [ $# -lt 1 ]; then
   echo "Usare ./ServersStats.sh <sito web> [<iterazioni>]";
   echo "sito web = l'indirizzo web di partenza";
   echo "iterazioni = livello di ricorsioni (default=5)";
   exit;
fi

iterations=$2

SERVERSFILE=$(date "+%Y%m%d%H%M%S")-Servers.txt

if [ -f sites.txt ]
then
   rm sites.txt
fi

if [ -f sites2.txt ]
then
   rm sites2.txt
fi

if [ -f Servers2.txt ]
then
   rm Servers2.txt
fi

curl -s $1 | tr '"' \\n | tr '=' \\n | tr ' ' \\n | tr '?' \\n | grep ^http: | sort | uniq | tr '/' \\n | grep ^www | sort | uniq >> sites.txt
curl -s $1 | tr '"'' ''?''=''%' \\n 2>/dev/null | grep ^http: | cut -c8- | cut -f1 -d'/' | sort | uniq  >> sites.txt

for (( i=1; i<=${iterations:=5}; i++ ))
do
   sites_array=($(cat sites.txt))
   for j in ${sites_array[*]}
   do
      curl -s $j | tr '"' \\n | tr '=' \\n | tr ' ' \\n | tr '?' \\n | grep ^http: | sort | uniq | tr '/' \\n | tr '?' \\n  | grep ^www | sort | uniq >> sites.txt
      if curl -sI $j >/dev/null 2>&1
      then
         curl -s $j | tr '"'' ''?''=''%' \\n 2>/dev/null | grep ^http: | cut -c8- | cut -f1 -d'/' | sort | uniq >> sites.txt
      fi
   done
   sort sites.txt | uniq > sites2.txt
   cp sites2.txt sites.txt
done

unset sites_array

sites_array=($(cat sites.txt))

echo Trovati ${#sites_array[*]} siti ...

for j in ${sites_array[*]}
do
   curl -sI $j | grep "^Server:" | cut -c9- >> $SERVERSFILE
done

SERVERSFILESIZE=$(cat $SERVERSFILE | wc -l)

echo
echo Percentuale server Apache: $(( 100 * $(grep Apache $SERVERSFILE | wc -l)/$SERVERSFILESIZE ))'%' di tutti i server Apache
echo Percentuale server Microsoft IIS: $(( 100 * $(grep Microsoft $SERVERSFILE | wc -l)/$SERVERSFILESIZE ))'%' di tutti i server Microsoft IIS

sort $SERVERSFILE | uniq -c | sort -nr > Servers2.txt
mv Servers2.txt $SERVERSFILE

echo
echo "Vedere file $SERVERSFILE per la lista completa dei server copiati"

71 Un dispositivo mobile supporta la memorizzazione di files, ma non con la consueta struttura gerarchica presente nel file system di un computer.
Si desidera trasferire nel dispositivo mobile i file presenti in una directory A organizzata
gerarchicamente nel proprio computer e, per permettere tale trasferimento con un unica operazione di drag&drop, occorre eliminare la sua struttura gerarchica e portare tutti i file allo stesso livello.
Scrivere uno script bash che, a partire dalla directory A passata come argomento, crei un'altra directory B nella quale tutti i file contenuti in A siano ancora presenti ma tutti allo stesso livello. Fare ciò curando che la directory A sia lasciata intatta e, dal momento che l'operazione
si svolge in un disco quasi pieno, fare anche in modo che sia consumata la minore quantità di memoria permanente possibile.

#!/bin/bash
percorso=$(pwd)
mkdir $2
find ./$1 -type f  > elenco.txt
a=$(wc -l elenco.txt | awk '{print $1}')
i=1
while [ $i -le $a ]
do
            riga=$(head -$i elenco.txt | tail -1)
            riganuova=$(echo ${riga:1})
            nome=$(echo ${riga##.*/})
            echo "***$percorso$riganuova $percorso/$2/$nome"
            cp $percorso$riganuova $percorso/$2/$nome
            let i++
done

71 Trovare, tra quelli che possono essere lanciati dalla linea di comando senza indicare esplicitamente il loro percorso, l'eseguibile che ha la maggiore dimensione del proprio codice (ovvero della propria sezione testo).

#!/bin/bash
find . -perm +111 -type f > elenco.txt
a=$(wc -l elenco.txt | awk '{print $1}')
max=0
i=1
while [ $i -le $a ]
do
            file=$(head -$i elenco.txt | tail -1)
            grandezza=$(cat $file | wc -l | awk '{print $1}')
            if [ $grandezza -gt $max ]
            then
                       max=$grandezza
                       filemax=$(echo ${file##.*/})
            fi
let i++
done
echo "Il file più grande è $filemax!"
           
PROCESSI, MEMORIA, SISTEMA E COMANDI
WEB E SEGNALI
COPIA, RICERCA, SPOSTAMENTO, TRASFORMAZIONI, LINK, SCRIPT, RANDOM ECC ECC
PASSWORD, INSERIMENTI, PERMESSI, CODIFICHE, ESTENSIONI FILE E ARCHIVI