9.9. Comandi di controllo
Indietro | Capitolo 9. Programmazione di shell | Avanti

## 9.9. Comandi di controllo

### 9.9.1. Condizionale if

L'espressione condizionale `if` è disponibile in entrambe le shell, ma con una diversa sintassi.

#### 9.9.1.1. Sh

`if` `condizione1` `then` lista di comandi se `condizione1` è vera (true) [`elif` `condizione2` `then` lista di comandi se `condizione2` è vera (true)] [`else` lista di comandi se `condizione1` è falsa (false)] `fi`

Le condizioni sono sottoposte usualmente al comando test(1) o `[]` (Vedere la sezione 9.9.6). L'`if` e `then` devono essere separati con un newline o un punto e virgola (;).

#!/bin/sh if [ $# -ge 2 ] then echo $2 elif [ $# -eq 1 ]; then echo $1 else echo Nessun input fi

Sono richiesti degli spazi nel formato della condizione di test(1), uno dopo `[` e uno prima di `]`. Questo script potrebbe comportarsi in modo differente a seconda che ci siano zero, uno o più argomenti su linea di comando. Iniziando con nessun argomento:

$ `./if.sh` Nessun input

Ora con un argomento:

$ `./if.sh one` one

E ora con due argomenti:

$ `./if.sh one two` two

#### 9.9.1.2. Csh

`if` (`condizione`) ``comando`` -oppure- `if` (`condizione1`) `then` lista di comandi se `condizione1` è vera (true) [`else` `if` (`condizione2`) `then` lista di comandi se `condizione2` è vera (true)] [`else` lista di comandi se `condizione1` è falsa (false)] `endif`

L'`if` e `then` devono stare sulla stessa linea.

#!/bin/csh -f if ( $#argv >= 2 ) then echo $2 else if ( $#argv == 1 ) then echo $1 else echo Nessun input endif

Di nuovo, questo script potrebbe comportarsi in modo differente a seconda che ci siano zero, uno o più argomenti su linea di comando. Iniziando con nessun argomento:

`%` `./if.csh` Nessun input

Ora con un argomento:

`%` `./if.csh one` one

E ora con due argomenti:

`%` `./if.csh one two` two

### 9.9.2. Condizionale switch e case

Per scegliere tra una serie di valori di tipo stringa relativi a un parametro si usa `case` nella shell Bourne e `switch` nella shell C.

#### 9.9.2.1. Sh

`case` `parametro` `in` `schema1`[|`schema1a`]) `lista1 di comandi`;; `schema2`) `lista2 di comandi` `lista2a di comandi`;; `schema3`) `lista3 di comandi`;; *) ;; `esac`

Si possono usare validi nomi di file meta-caratteri all'interno dello schema per il confronto. I ;; concludono ogni scelta e possono essere sulla stessa linea della scelta o a seguito di un newline, dopo l'ultimo comando per la scelta. Schemi alternativi per la scelta di un particolare caso sono separati da una barra verticale |, come nel primo schema dell'esempio precedente. I simboli wild card ,? per indicare un generico carattere e * per far corrispondere alcuni caratteri, possono essere usati singolarmente o in modo adiacente per completare stringhe.

Questo semplice esempio illustra come usare l'espressione condizionale `case`.

#!/bin/sh case $1 in aa|ab) echo A ;; b?) echo "B \c" echo $1;; c*) echo C;; *) echo D;; esac

Quindi quando si esegue lo script con l'argomento posto sulla colonna di sinistra, lo script risponde come sulla colonna di destra:

aa | A
ab | A
ac | D
bb | B bb
bbb | D
c | C
cc | C
fff | D

#### 9.9.2.2. Csh

`switch` (`parametro`) `case` `schema1`: `lista1 di comandi` [`breaksw`] `case` `schema2`: `lista2 di comandi` [`breaksw`] `default`: lista di comandi per il comportamento di default [`breaksw`] `endsw`

`breaksw` è opzionale e può essere usato per interrompere lo switch dopo che si è verificata una corrispondenza del valore di tipo stringa del parametro confrontato. `Switch` non accetta | nella lista degli schemi, ma permette di unire insieme diverse strutture `case` per fornire un simile risultato. Il seguente script di shell C ha lo stesso comportamento dell'esempio precedente, riferito al `case` della shell Bourne.

#!/bin/csh -f switch ($1) case aa: case ab: echo A breaksw case b?: echo -n "B " echo $1 breaksw case c*: echo C breaksw default: echo D endsw

### 9.9.3. for e foreach

Per effettuare un ciclo tra una lista di valori di tipo stringa si possono usare i comandi `for` e `foreach`.

#### 9.9.3.1. Sh

`for` `variabile` [`in` `lista_di_valori`] `do` `lista di comandi` `done`

La `lista_di_valori` è opzionale, presupponendo `$@` se nulla viene specificato. Ogni valore in questa lista viene sostituito sequenzialmente in `variabile` fino a quando la lista risulta vuota. Possono essere usati wild card, che vengono applicati ai nomi dei file nella directory corrente. Di seguito si illustra il ciclo `for` che copia tutti i file che finiscono con `.old` negli stessi nomi che finiscono però con `.new`. In questi esempi l'utility basename(1) estrae la parte base del nome affinchè si possa modificarne l'estensione.

#!/bin/sh for file in *.old do newf=`basename $file .old` cp $file $newf.new done

#### 9.9.3.2. Csh

`foreach` `variabile` (`lista_di_valori`) `lista di comandi` `end`

L'equivalente script in shell C per copiare tutti i file con estensione `.old` negli stessi file con estensione `.new` è:

#!/bin/csh -f foreach file (*.old) set newf = `basename $file .old` cp $file $newf.new end

### 9.9.4. while

Il comando `while` permette di effettuare il ciclo sempre che la condizione sia vera.

#### 9.9.4.1. Sh

`while` `condizione` `do` `lista di comandi` [`break`] [`continue`] `done`

Un semplice script per illustrare il ciclo `while` è:

#!/bin/sh while [ $# -gt 0 ] do echo $1 shift done

Questo script prende la lista degli argomenti, ne visualizza il primo, quindi effettua uno shift nella lista verso sinistra, perdendo il primo elemento originale. Il ciclo viene ripetuto fino a quando tutti gli argomenti sono stati spostati fuori dalla lista.

$ `./while.sh one two three` one two three

#### 9.9.4.2. Csh

`while` (`condizione`) `lista di comandi` [`break`] [`continue`] `end`

Se si vuole che la condizione sia sempre vera si specifica 1 all'interno del test condizionale.

Lo script di shell C equivalente a quello precedente è:

#!/bin/csh -f while ($#argv != 0 ) echo $argv[1] shift end

### 9.9.5. until

Questo costrutto di ciclo è solamente disponibile per la shell Bourne.

`until` `condizione` `do` lista di comandi se la condizione è falsa `done`

La condizione viene verificata all'inizio di ogni ciclo e il ciclo termina quando la condizione è vera.

Uno script equivalente all'esempio del `while` precedente è:

#!/bin/sh until [ $# -le 0 ] do echo $1 shift done

Si noti che qui si verifica per minore o uguale, piuttosto che per maggiore, poichè il ciclo `until` viene abilitato da una condizione falsa.

Sia il ciclo `until` che il `while` sono solamente eseguiti se la condizione è soddisfatta. La condizione viene valutata prima dell'esecuzione dei comandi.

### 9.9.6. test

Le espressioni condizionali vengono valutate per valori veri o falsi. Questo, di solito, viene realizzato con test(1) o equivalentemente con i suoi operatori `[]`. Se la condizione viene valutata vera, viene settato uno stato di uscita zero (TRUE), altrimenti viene settato uno stato di uscita non-zero (FALSE). Se non ci sono argomenti viene settato uno stato di uscita non-zero. Gli operatori utilizzati nelle espressioni condizionali della shell Bourne sono mostrati qui sotto.

Per i nomi di file le opzioni per test(1) sono date con la sintassi seguente:

`-`opzione`` `filename`

Le opzioni di test(1) disponibili per i file includono:

`-r` | vero se il file esiste ed è leggibile
`-w` | vero se il file esiste ed è scrivibile
`-x` | vero se il file esiste ed è eseguibile
`-f` | vero se il file esiste ed è un file regolare (o per csh(1) esiste e non è una directory)
`-d` | vero se il file esiste ed è una directory
`-h` o `-L` | vero se il file esiste ed è un link simbolico
`-c` | vero se il file esiste ed è un file speciale a caratteri (ad esempio un dispositivo al quale si accede un carattere alla volta)
`-b` | vero se il file esiste ed è un file speciale a blocchi (ad esempio un dispositivo al quale si accede in blocchi di dati)
`-p` | vero se il file esiste ed è un file pipe (fifo)
`-u` | vero se il file esiste ed è setuid (ad esempio ha il bit set-user-id settato a s o S nel terzo bit)
`-g` | vero se il file esiste ed è setgid (ad esempio ha il bit set-group-id settato a s o S nel sesto bit)
`-k` | vero se il file esiste e ha lo sticky bit settato (una t nel nono bit)
`-s` | vero se il file esiste ed ha una dimensione maggiore di zero

C'è un test per i descrittori di file:

`-t [`descrittore_file`]` | vero se l'aperto descrittore del file specificato (1, stdout(4), di default) è associato ad un terminale

Ci sono test per le stringhe:

`-z `stringa`` | vero se la lunghezza della stringa è zero
`-n `stringa`` | vero se la lunghezza della stringa non è zero
``stringa1` = `stringa2`` | vero se `stringa1` è identica a `stringa2`
``stringa1` != `stringa2`` | vero se `stringa1` non è identica a `stringa2`
`stringa` | vero se la stringa non è nulla

Ci sono dei confronti per gli interi:

``n1` -eq `n2`` | vero se gli interi `n1` e `n2` sono uguali
``n1` -ne `n2`` | vero se gli interi `n1` e `n2` non sono uguali
``n1` -gt `n2`` | vero se l'intero `n1` è maggiore dell'intero `n2`
``n1` -ge `n2`` | vero se l'intero `n1` è maggiore o uguale dell'intero `n2`
``n1` -lt `n2`` | vero se l'intero `n1` è minore dell'intero `n2`
``n1` -le `n2`` | vero se l'intero `n1` è minore o uguale dell'intero `n2`

Sono disponibili i seguenti operatori logici:

`!` | negazione (unaria)
`-a` | and (binario)
`-o` | or (binario)
`()` | le espressioni all'interno di ( ) vengono raggruppate insieme. Può essere necessario quotare le parentesi ( ) per impedire alla shell di interpretarle.

### 9.9.7. Operatori relazionali e logici della shell C

La shell C possiede un suo set di operatori logici e relazionali built-in. In ordine decrescente di priorità questi sono:

`(...)` | raggruppa espressioni con ( )
`~` | inverso (il suo complemento)
`!` | negazione logica
`*, /, %` | moltiplicazione, divisione, modulo
`+, -` | addizione, sottrazione
`<<, >>` | shift a sinistra di bit, shift a destra di bit
`<=` | minore o uguale
`>=` | maggiore o uguale
`<` | minore
`>` | maggiore
`= =` | uguale
`!=` | non uguale
`=~` | uguale a stringa
`!~` | non uguale a stringa
`&` | AND bit
`^` | XOR bit (or esclusivo)
`|` | OR bit
`&&` | AND logico
`||` | OR logico
`{`comando`}` | vero (1) se il comando termina con uno stato di uscita 0, falso (0) altrimenti.

Inoltre la shell C permette richieste sul tipo e sui permessi dei file con gli operatori seguenti:

`-r` | ritorna vero (1) se il file esiste ed è leggibile, altrimenti ritorna falso (0)
`-w` | vero se il file esiste ed è scrivibile
`-x` | vero se il file esiste ed è eseguibile
`-f` | vero se il file esiste e non è una directory
`-d` | vero se il file esiste ed è una directory
`-e` | vero se il file esiste
`-o` | vero se l'utente corrente è il proprietario del file
`-z` | vero se il file ha una lunghezza zero (file vuoto)

Indietro | Risali | Avanti
9.8. Funzioni | Partenza | Capitolo 10. Editor

Questo, ed altri documenti, possono essere scaricati da ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/

Per domande su FreeBSD, leggi la documentazione prima di contattare <questions@FreeBSD.org>.
Per domande su questa documentazione, invia una e-mail a <doc@FreeBSD.org>.