Costrutti di Flusso
Costrutto while
Sintassi:
while comando
do
istruzioni
done
Il ciclo viene eseguito fintanto che lo stato di ritorno del comando è zero (successo)
- Se al primo giro il comando già fallisce il ciclo non è mai eseguito
- Il comando è spesso implementato come istruzione di test
Occorre che le istruzioni del ciclo modifichino opportunamente gli operandi dell'espressione logica testata o si può incorrere in un ciclo infinito
Se si desidera un ciclo infinito lo si ottiene con:
while true
Due comandi utili:
true
- ritorna successofalse
- ritorna fallimento
Esempio.
(while1.sh)
#! /bin/bash
count=10
while ((count > 0))
do
echo $count
sleep 1
count=$((count-1))
done
Compie un conto alla rovescia da 10 a 1 inclusi, con un secondo di intervallo tra ogni numero.
Note sulle parentesi
(( … ))
- racchiudono un'espressione logica e ritornano 0 se vera e 1 se falsa$( … )
- restituiscono l'output di un comando$(( … ))
- restituiscono il risultato dell'operazione aritmeticasleep n
- attenden
secondi
Esempio variante al precedente.
(while1a.sh)
#! /bin/bash
count=10
while ((count > 0))
do
echo $((count--))
sleep 1
done
Operaratori di autoincremento e autodecremento
- Incrementano o decrementano di 1 la variabile
var++
var--
- usano la variabile prima++var
--var
- usano la variabile dopo- Sono gli stessi del linguaggioC
- Devono comarire in espressioni
$(( ... ))
Costrutto until
Sintassi:
until comando
do
istruzioni
done
Il ciclo viene sospeso quando lo stato di ritorno del comando è zero (successo)
- Se al primo giro il comando ha già successo il ciclo non è mai eseguito
- Naturalmente il comando è spesso un'espressione di test
Esempio.
(until1.sh)
#! /bin/bash
count=10
until ((count == 0))
do
echo $count
sleep 1
count=$((count-1))
done
Attenzione agli operatori nel contesto (( ... ))
=
- di assegnazione==
- di paragone di uguaglianza!=
- di paragone di differenza
Costrutto for
Prima forma:
for variabile in lista
do
istruzioni
done
Ove:
do
edone
delimitano le istruzioni di ciclo- La variabile assume ad ogni ciclo il valore successivo della lista
- La lista è esplicita o generata con un comando
- I cicli terminano quando l'intera lista è stata scandita *Eventuali errori intermedi non terminano la scansione della lista
Esempio.
(for1.sh)
#! /bin/bash
(($# == 0)) && echo "no args given" >&2 && exit 1
[ ! -d $1 ] && echo "$1 not a dir" >&2 && exit 2
[ ! -r $1 ] && echo "cannot read $1" >&2 && exit 3
subs=0
for i in $(ls $1)
do
if [ -d $1/$i ]
then
((subs++))
fi
done
echo "$1 has $subs subdirs"
Seconda forma del costrutto for:
for (( iniz; cond; loop ))
do
istruzioni
done
ove:
iniz
è un'istruzione eseguita prima del ciclo- possono essere più istruzioni se separate da virgole
cond
è la condizione logica di esecuzione del cicloloop
è un'istruzione eseguita alla fine di ciascun ciclo
Questo tipo di for è preso dal linguaggio C
Esempio.
(for2.sh)
#! /bin/bash
for ((i=1;i<11;i++))
do
for ((j=1;j<11;j++))
do
echo -ne "$((i*j))\t"
done
echo
done
Ove:
-n
- non va a capo-e
- riconosce i caratteri di escape come \t (tab)echo
da solo produce una linea vuota
Esempio migliorato.
(for2a.sh)
#! /bin/bash
for ((i=1;i<11;i++))
do
for ((j=1;j<11;j++))
do
printf "%5d" $((i*j))
done
echo
done
printf
printf
- print formattato
printf "formato" arg1 arg2 …
- La stringa di formato può contenere dei segnalini di formato di argomento del tipo
%fff
- Deve esserci un argomento per ogni segnalino
- I segnalini sono gli stessi dell'equivalente funzione del linguaggio C
Segnalini di formato, esempi:
%d
- numero intero decimale%x
- numero intero esadecimale%5d
- intero decimale in un campo di 5 caratteri%10,2f
- numero float in un campo di 10 caratteri con 2 caratteri dopo la virgola%s
stringa
Anche i caratteri di escape sono riconosciuti all'interno delle stringhe di formattazione.
Comandi break
e continue
Si possono usare con while
, until
e for
Il comando break
esce dal ciclo corrente e manda il controllo all'istruzione dopo il done
Il comando continue
manda il controllo all'istruzione done saltando le rimanenti istruzioni del ciclo
- Inizia quindi un nuovo ciclo con l'esecuzione del comando di while o until o l'elemento successivo del for
Esempio.
(break1.sh)
#! /bin/bash
[ $# -lt 1 ] \
&& echo "usage: $0 divisor [max]" >&2 \
&& exit 1
max=${2:-1000}
i=0
while true
do
((++i > max)) && break
(( (i%$1) != 0)) && continue
tput smso
printf "%5d" $i
tput sgr0
printf " "
done
echo -e "\nEnded"