PROGRAMMAZIONE SHELL

LPIC1 Certification Bible - Parte III - Capitolo 14

Cenni preliminari

Per convenzione i file contenenti uno script bash hanno estensione .sh

Il file di script deve iniziare specificando l'interprete, la forma è:
#!/bin/bash
o la forma abbreviata:
#!/bin/sh

Lo script si lancia con la forma:
# nomefile.sh [argomento1] [argomento2] ... [argomento n]

ATTENZIONE:
Per essere eseguito lo script deve averne i permessi, che possono essere dati così:

# chmod u+x nomefile.sh

oppure deve essere lanciato con il comando:

# bash nomefile.sh

Argomenti

Se un programma necessita di argomenti specificati al momento del lancio, al'interno dello script questi hanno la sintassi $n, dove n è il numeo dell'argomento.
Opzionalmente si può usare $* per indicare tutti gli argomenti.

ESEMPIO:
#!/bin/bash

#il cancelletto dichiara la linea come commento, è bene usare molti
# commenti per una modifica futura del codice

#Questo script esegue il comando 'ls -la' mostrando solo il tipo di file dichiarato
# dall'argomento e mette in pipe con 'more' il risultato
ls -la *.$1 | more

Se, ad esempio, il file si chiama provascript.sh e voglio visualizzare i file .txt dovrò lanciarlo con la sitassi:

#provascript.sh txt

Variabili

Le variabili vengono dichiarate nel momento del loro primo assegnamento, eseguito con l'operatore =

PIPPO=0

Da notare l'assenza di spazi prima e dopo l'uguale. Se la variabile contiene degli spazi devono essere usate le doppie virgolette

NOME="Nome Cognome"

Dal momento della dichiarazione le variabili sono richiamabili con la forma
$pippo

ESEMPIO:
#!/bin/bash
PIPPO=3
DOPPIOPIPPO=$PIPPO*2
echo "Il doppio di $PIPPO è $DOPPIOPIPPO"

Per rimuovere una variabile precedentemente settata si usa il comando:
unset PIPPO

:: Tempo di vita di una variabile

Quando una variabile viene dichiarata è una variabile di shell e morirà con essa.
Affinché la variabile diventi una variabile d'ambiente (ovvero sempre valida) è necessario il comando export.
Digitando solo

#export

verrà stampata a video la lista di tutte le variabili d'ambiente (provare anche con l'ozione -p).
Col comando

#set

verranno invece stampate a video tutte le variabili di shell (anche quelle non esportate).
Per esportare una specifica variabile il comando è:

#export variabile
oppure (per dichiarare ed esportare una variabile in un solo passaggio)
#export variabile=valore

Se la variabile, invece, deve valere solo all'interno di un dato processo si usa la sintassi:

#$variabile=valore comando

:: Quotare una variabile

Nell'uso delle variabili è importante comprendere la funzione di alcuni caratteri di quotazione, come " ' \

Ad esempio, con il seguente comando:

#echo 2 + 3 > 1 + 1

il segno di maggiore sarà interpretato come redirezione e il risultato del comando sarà un file chiamato 1.
Per stampare caratteri speciali si dovranno invece seguire le seguenti forme:

#echo '2 + 3 > 1 + 1'
o
#echo 2 + 3 '>' 1 + 1
o
#echo 2 + 3 \> 1 + 1

Il sistema stamperà a video

2 + 3 > 1 + 1

La seguente tabella può essere più esplicativa

ESEMPI DI QUOTAZIONI
NAME=nome
Espressione
Risultato
$NAME
nome
"$NAME"
nome
\$NAME
$NAME
'$NAME'
$NAME
"'$NAME'"
'nome'
"~nome"
~nome
'~nome'
~nome
~nome
/home/nome

L'ultima quotazione da prendere in esame si esegue col simbolo ` (ALT-96 e non l'apice singolo!) e serve per ritornare un comando.
Ad esempio :

#echo `date`

stamperà a video il risultato del comando date (la data e l'ora corrente)

Controllo del flusso del programma

All'interno dello script può essere necessario usare delle strutture che controllino lo scorrimento del programma.
Le strutture a disposizione sono:

:: L'istruzione if / else

If è l'istruzione che permette di eseguire una operazione dopo che la condizione è stata controllata e passata.
Possiamo dividere l' if in 3 possibili strutture:

if condizione
    then
        
operazione
fi

----------

if condizione
    then
        
operazione1
    else
        
operazione2
fi

----------

if condizione
    then
        
operazione1
    
[elif condizione2
        then
            
operazione2]
    
[else
        
operazione3]
fi

In tutti e tre i casi notiamo come l'istruzione finisce con l'istruzione fi (il contrario di if).

Nel primo caso l'operazione viene eseguita solo se la condizione risulta vera, altrimenti lo script continua.

Nel secondo caso lo script andrà avanti solo dopo che una delle due operazioni è stata eseguita. La prima, se la condizione viene soddisfatta, altrimenti la seconda.

Nell'ultimo caso le condizioni possono essere impilate cosicché le operazioni siano diverse a seconda delle condizioni. Se nessuna delle condizioni termina con valore VERO viene eseguita l'operazione in else.

NOTA:
Le parentesi quadre non in corsivo indicano l'opzionalità del contenuto

:: Il ciclo for

Si usa quando si vuole effettuare la stessa istruzione utilizzando ogni volta la variabile di iniziazione con un valore diverso

for variabile [in lista]
    do
        istruzione (contenente $variabile)
done

variabile avrà ad ogni ciclo il valore definito in lista.
Se in lista viene omesso vengono usati i valori passati col lancio dello script

ESEMPI:

for colore in "bianco" "nero" "rosso"
    do
        echo "Il mio colore preferito è il $colore"
done

Questo script stamperà a video:

Il mio colore preferito è il bianco
Il mio colore preferito è il nero
Il mio colore preferito è il rosso

-------------------------

echo "Gli utenti del sistema sono:"
for utente in `ls /home`
    do
        echo "$utente"
done

Questo script stamperà a video:

Gli utenti del sistema sono:
utente1
utente2
...

:: L'istruzione case

L'istruzione case confronta una stringa con delle possibilità ed esegue l'istruzione collegata alla possibilità che risulta corretta.

case stringa in
    possibilità1 )
        istruzione ;;
    possibilità2 )
        istruzione ;;
    possibilità3 )
        istruzione ;;
...
esac

ESEMPIO:

case $nomefile in
    *.doc )
        echo "Il file $nomefile è un documento" ;;
    *.txt )
        echo "Il file $nomefile è un file di testo" ;;
    *.gif|*.jpg|*.png )
        echo "Il file $nomefile è una immagine" ;;
esac

:: Le istruzioni while e until

L'istruzione while esegue il ciclo finché la condizione non restituisce FALSO.

while condizione
    do
        
istruzione
done

Contrariamente al while, l'istruzione until contunua il ciclo finché la condizione non restituisce VERO.

until condizione
    do
        
istruzione
done

NOTA:
Per evitare dei loop infiniti l'istruzione in genere modifica il valore della variabile di confronto.

ESEMPI:

Di seguito due esempi molto simili eseguiti con while e until.

while [ $value -lt 50 ]
    do
        $value = $(($value+1))
done

----------

until [ $value -eq 50 ]
    do
        value = $(($value+1))
        echo $value
done

TEST ARITMETICI
Test
Funzione
-lt
(Less than) Più piccolo di
-le
(Less or Equal to) Minore o uguale di
-eq
(Equal to) Uguale a
-ge
(Greater or Equal to) Maggiore o uguale di
-gt
(Greater than) Più grande di
-ne
(Not equal to) Diverso da
NOTA:
I test seguono la sintassi del comando test, per maggiori informazioni leggerne il manuale con il comando:
#man test