Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Iterazioni: i cicli for, while ed until

Imparare a conoscere i cicli di base supportati dalla Shell e da Bash: for, while ed until.
Imparare a conoscere i cicli di base supportati dalla Shell e da Bash: for, while ed until.
Link copiato negli appunti

Praticamente tutti i linguaggi di programmazione possiedono il concetto di ciclo: se si vuole ripetere un'azione venti volte, non c'è bisogno di scrivere ripetutamente lo stesso codice, magari modificandolo leggermente ogni volta. Utilizzare un ciclo consente di evitare proprio questo tipo di problema. Anche in Bash è possibile utilizzare i classici costrutti for e while come nei più classici linguaggi di programmazione.

Cicli for

Un ciclo for itera una serie di valori finché la lista non si esaurisce:

for i in 1 2 3 4 5
do
  echo "Numero $i"
done

Eseguendo lo script precedente, la variabile $i assume ciascuno dei valori indicati dopo la parola chiave in nello stesso ordine; i valori assunti possono essere di qualsiasi tipo, come si vede nell'esempio che segue:

for i in 1 2 topolino pippo 3 pluto
do
  echo "i ha valore $i"
done

Per scorrere una lista di numeri interi è possibile anche usare la scorciatoia {1..10}, che in questo caso specifico corrisponde allo scrivere 1 2 3 4 5 6 7 8 9 10. Bash offre anche una sintassi alternativa per specificare cicli for su liste di numeri interi, derivata da quella più diffusa e basata su C:

#!/bin/bash
for (( i = 0 ; i <= 20 ; i += 2 )) ; do
  echo "i ha valore $i"
done

Questo ciclo for usa tre diverse espressioni aritmetiche, separate da ; (e non da , poiché sono tre espressioni separate, non semplici sotto-espressioni). La prima rappresenta l'inizializzazione, che viene eseguita prima che il ciclo inizi. La seconda è l'espressione di test, valutata prima di ogni potenziale iterazione del ciclo (inclusa la prima): se vale 0 (falso), il ciclo termina. La terza è l'espressione di conteggio e viene eseguita alla fine di ogni iterazione. Utilizzando questa nuova sintassi e quella che abbiamo visto usare per specificare espressioni aritmetiche, è possibile definire cicli su sequenze di numeri arbitrarie: nel seguente esempio la sequenza di valori stampata corrisponde ai primi 10 elementi della successione di Fibonacci.

#!/bin/bash
for (( i = 1 , j = 1 ; i <= 34 ; i += j, j += i )) ; do
  echo -n "$i" "$j "
done
echo

Cicli while ed until

Un costrutto più flessibile del for per definire cicli è il while: è simile al costrutto if che abbiamo visto nella sezione precedente, ma a differenza di quest'ultimo ripete i comandi fino a che la condizione specificata continua ad essere valutata come vera. Ad esempio, supponiamo di voler attendere finché il file attesa.txt venga eliminato. Un possibile approccio è quello di attendere per alcuni secondi (cioè non fare niente), per poi controllare se il file esiste ancora, ripetendo ciò continuamente in questo modo:

while [[ -e attesa.txt ]] ; do
  sleep 3 # "dormi" per tre secondi
done

Un modo alternativo ma altrettanto valido è quello di usare il ciclo until, che funziona in maniera simile al while, ma nel modo inverso: esso infatti, continua ad eseguire i comandi fintantoché la condizione specificata è false, e termina nel momento in cui essa risulta vera. Ad esempio, se si volesse attendere fintantochè il file procedi.txt venga creato, si potrebbe utilizzare il seguente script:

until [[ -e procedi.txt ]] ; do
  sleep 3 # "dormi" per tre secondi
done

Ovviamente, si otterrebbe il medesimo risultato utilizzando il ciclo while e negando (!) la condizione contenuta nel comando test, ma in alcuni casi impiegare l'until potrebbe migliorare la leggibilità del codice.

Utilizzare il ciclo while è molto utile quando si vuol mantenere uno script in esecuzione finchè l'utente non decida di interromperlo, in questo modo:

echo "Inserisci un messaggio (esci per uscire)"
while [[ $INPUT != "esci" ]]
do
  read INPUT
  echo "Hai digitato: $INPUT"
done

Infine, esistono alcune situazioni particolari in cui non è possibile specificare una condizione chiara e prefissata da testare ad ogni ciclo while, perciò la maggior parte dei linguaggi di programmazione offre la possibilità di definire cicli senza condizione che vengono eseguiti all'infinito. In Bash il simbolo : viene valutato sempre come vero, perciò utilizzarlo come condizione di un ciclo while impone a quest'ultimo di eseguire le istruzioni in esso contenute all'infinito. L'unico modo per interrompere l'esecuzione a livello di codice è quello di utilizzare il comando break, che ha l'effetto di interrompere immediatamente il ciclo che lo contiene. Alla luce di questo, possiamo riscrivere l'esempio precedente in questo modo:

#!/bin/bash
echo "Inserisci un messaggio (esci per uscire)"
while :
do
  read INPUT
  if [[ $INPUT = "esci" ]] ; then
    break
  fi
  echo "Hai digitato: $INPUT"
done

Ti consigliamo anche