Loop

Come nella maggior parte dei linguaggi di programmazione, in Bash è possibile realizzare dei cicli. Tuttavia, ci sono delle differenze sostanziali in come vengono gestiti gli insiemi di indici da iterare.

Ciclo for

Un ciclo for in bash itera su una lista di elementi, specificati separandoli con degli spazi. Ad esempio, si provi ad inserire il seguente pezzo di codice in uno script (o lo si esegua direttamente nel terminale):

for i in a b c; do
  echo $i
done
L'output saranno tre righe, contenente rispettivamente "a", "b", e "c". Il loop itera su tutti gli argomenti specificati, e la variabile i viene impostata di volta in volta all'elemento corrente.

È possibile simulare il comportamento di un for che itera su un indice, creando una sequenza di interi con il comando seq M N, che produce tutti gli interi da M ad N estremi inclusi (separati da spazi).

Si scriva uno script che iteri su tutti gli interi da 0 a 100, e stampi l'intero nel caso in cui esso sia strettamente minore del minuto corrente, il suo doppio altrimenti. Ad esempio, nel caso fossero le 16:04 dovremmo vedere come output:
1
2
3
4
10
12
14
...
Ovviamente, per implementare questo comando ci sarà bisogno dell'istruzione if, oltre che del ciclo for.

Il ciclo while

Il ciclo while permette di iterare fino a che una certa condizione non si avvera. La sintassi per la condizione è la stessa usata per l'if. Ad esempio, se volessimo scrivere uno script che attende la creazione di un file test.txt leggibile, e quando lo trova lo stampa ed esce, potremmo scrivere:

#!/bin/bash

while [ ! -r test.txt ]; do
  sleep 1
done

cat file.txt
Abbiamo usato il comando sleep per attendere un secondo fra una richiesta e l'altra, e non occupare la CPU al 100%.

Globbing

Per generare della liste su cui iterare, ci sono due strategie solitamente adottate:

Utilizzando la seconda strategia, potremmo ad esempio iterare su tutti i file .txt nella cartella corrente con le istruzioni:
#!/bin/bash

for file in *.txt; do
  cat $file
done
Le possibiltà sono molteplcici. Ad esempio, file.{txt,csv,sh} viene automaticamente espanso come file.txt file.csv file.sh. È possibile trovare ulteriori informazioni leggendo il manuale sull'argomento con man 7 glob.

Proviamo a fare un esempio concreto. Se usiamo la combinazione di globbing {1..27} bash la espande come gli interi da 1 a 27, in maniera completamente analoga a chiamare seq 1 27. Possiamo dunque controllare se i PC dell'Aula 4 sono attivi con il comando:

$ for i in {1..27}; do ping -c 1 lab$i.cs.dm.unipi.it; done