L'espressione condizionale if è
disponibile in entrambe le shell, ma con una diversa sintassi.
ifcondizione1thenlista di comandi secondizione1è vera (true) [elifcondizione2thenlista di comandi secondizione2è vera (true)] [elselista di comandi secondizione1è 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 inputOra con un argomento:
$ ./if.sh one
oneE ora con due argomenti:
$ ./if.sh one two
twoif(condizione)comando-oppure-if(condizione1)thenlista di comandi secondizione1è vera (true) [elseif(condizione2)thenlista di comandi secondizione2è vera (true)] [elselista di comandi secondizione1è 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.cshNessun input
Ora con un argomento:
%./if.csh oneone
E ora con due argomenti:
%./if.csh one twotwo
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.
caseparametroinschema1[|schema1a])lista1 di comandi;;schema2)lista2 di comandilista2a 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;;
esacQuindi 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 |
switch(parametro)caseschema1:lista1 di comandi[breaksw]caseschema2: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
endswPer effettuare un ciclo tra una lista di valori di tipo
stringa si possono usare i comandi for e
foreach.
forvariabile[inlista_di_valori]dolista di comandidone
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
doneIl comando while permette di effettuare il ciclo
sempre che la condizione sia vera.
whilecondizionedolista di comandi[break] [continue]done
Un semplice script per illustrare il ciclo
while è:
#!/bin/sh
while [ $# -gt 0 ]
do
echo $1
shift
doneQuesto 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
threeQuesto costrutto di ciclo è solamente disponibile per la shell Bourne.
untilcondizionedolista di comandi se la condizione è falsadone
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
doneSi 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.
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:
-
opzionefilename
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
[ | vero se l'aperto descrittore del file specificato (1, stdout(4), di default) è associato ad un terminale |
Ci sono test per le stringhe:
-z
| vero se la lunghezza della stringa è zero |
-n
| vero se la lunghezza della stringa non è zero |
| vero se stringa1 è
identica a stringa2 |
| vero se stringa1 non è
identica a stringa2 |
stringa | vero se la stringa non è nulla |
Ci sono dei confronti per gli interi:
| vero se gli interi n1 e
n2 sono uguali |
| vero se gli interi n1 e
n2 non sono uguali |
| vero se l'intero n1 è
maggiore dell'intero n2 |
| vero se l'intero n1 è
maggiore o uguale dell'intero
n2 |
| vero se l'intero n1 è
minore dell'intero 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. |
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) |
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>.