Acquista questo Shell Scripting Tutorial come PDF per soli $5
Test è usato praticamente da ogni script di shell scritto. Potrebbe non sembrare così, perchétest
non è spesso chiamato direttamente. test
è più frequentemente chiamato come
if SPACE
Test is a simple but powerful comparison utility. For full details, run man test
sul vostro sistema, ma qui ci sono alcuni usi ed esempi tipici.
Test è più spesso invocato indirettamente attraverso le istruzioni if
ewhile
. È anche la ragione per cui avrete delle difficoltà se create un programma chiamato test
e cercate di eseguirlo, poiché questa shell builtin sarà chiamata al posto del vostro programma!
La sintassi per if...then...else...
è:
if then # if-codeelse # else-codefi
if ; then # do somethingfi
Puoi anche usare il elif
, come questo:
if ; then echo "Something" elif ; then echo "Something else" else echo "None of the above"fi
Prova il seguente frammento di codice, prima di eseguirlo imposta la variabile X a vari valori (prova -1, 0, 1, ciao, ciao, ecc). Puoi farlo come segue (grazie a Dave per aver sottolineato la necessità di esportare la variabile, come notato inVariabili - Parte I.):
$ X=5$ export X$ ./test.sh ... output of test.sh ...$ X=hello$ ./test.sh ... output of test.sh ...$ X=test.sh$ ./test.sh ... output of test.sh ...
Poi prova di nuovo, con $X
come nome di un file esistente, come /etc/hosts
.
test.sh
Nota che possiamo usare il punto e virgola (;
) per unire due linee. Questo viene spesso fatto per risparmiare un po' di spazio in semplici dichiarazioni if
.
Il backslash (\
) ha uno scopo simile, ma opposto: dice alla shell che questa non è la fine della linea, ma che la linea seguente dovrebbe essere trattata come parte della linea corrente. Questo è utile per la leggibilità. È consuetudine far rientrare la linea seguente dopo un backslash (\
) o un punto e virgola (;
).
Per esempio, il punto e virgola (;
) è spesso usato in questo modo per unire le parole chiave if
e then
:
if ; then echo "X is a file which is newer than /etc/passwd"fi
mentre il backslash (\
) è usato per dividere il comando a linea singola su due linee nel file dello script di shell, per motivi di leggibilità:
&& \ echo "X is a file which is newer than /etc/passwd"
Come vediamo da questi esempi, test
può eseguire molti test su numeri, stringhe e nomi di file.
C'è un modo più semplice di scrivere le dichiarazioni if
: I comandi &&
e ||
danno del codice da eseguire se il risultato è vero o falso, rispettivamente.
Questa sintassi è possibile perché c'è un file (o shell-builtin) chiamato che è raccomandato per cicli while e banali controlli sanitari con cui non si vuole distrarre eccessivamente il lettore.
Si noti che quando si imposta X su un valore non numerico, i primi confronti danno come risultato il messaggio:
Questo perché i confronti -lt, -gt, -le e -ge sono progettati solo per gli interi, e non funzionano sulle stringhe. I confronti tra stringhe, come !=
tratteranno felicemente "5" come una stringa, ma non c'è un modo sensato di trattare "Hello" come un intero, così i confronti tra interi si lamentano.
Se volete che il vostro script di shell si comporti con più grazia, dovrete controllare il contenuto della variabile prima di testarla - forse qualcosa del genere:
In questo modo potete echo
dare un messaggio più significativo all'utente, e uscire con grazia. La variabile $?
è spiegata in Variabili - Parte II, e grep
è una bestia complicata, quindi ecco qui: grep
trova le linee di testo che contengono cifre (0-9) ed eventualmente altri caratteri, quindi il cursore (^
) in grep
trova solo le linee che non consistono solo di numeri. Possiamo quindi fare il contrario (agendo sul fallimento, non sul successo). Va bene? Il >/dev/null 2>&1
dirige qualsiasi output o errore al dispositivo speciale "null", invece di andare sullo schermo dell'utente.
Molti ringraziamenti a Paul Schermerhorn per avermi corretto - questa pagina sosteneva che grep -v
avrebbe funzionato, ma questo è chiaramente troppo semplicistico.
Possiamo usare test in cicli while come segue:
test2.sh
#!/bin/shX=0while do echo "Enter some text (RETURN to quit)" read X echo "You said: $X"done
Questo codice continuerà a chiedere input fino a quando non si preme RETURN (X è di lunghezza zero).Grazie a Justin Heath per avermi fatto notare che lo script non funzionava - avevo dimenticato le virgolette intorno a $X nel while
. Senza quelle virgolette, non c'è niente da testare quando $X è vuoto.
Alexander Weber ha fatto notare che l'esecuzione di questo script finirà in modo disordinato:
Questo può essere messo in ordine con un altro test all'interno del ciclo:
#!/bin/shX=0while do echo "Enter some text (RETURN to quit)" read X if ; then echo "You said: $X" fidone
Nota anche che ho usato due sintassi diverse per le dichiarazioni if
in questa pagina. Queste sono:
if then echo "X is less than zero"fi.......... and ........if ; then echo "You said: $X"fi
Devi avere una pausa tra la frase if
e il costrutto then
. Questo può essere un punto e virgola o un newline, non importa quale, ma ci deve essere uno o l'altro tra il if
e il then
.Sarebbe bello dire solo:
if echo "You said: $X"
ma il then
e il fi
sono assolutamente necessari.
Indietro: Loop Next: Caso