Cumpărați acest Tutorial de scripting shell în format PDF pentru numai 5$
Testul este folosit practic de fiecare script shell scris. S-ar putea să nu pară așa, deoarecetest
nu este adesea apelat direct. test
este mai frecvent apelat ca
if SPACE
Test is a simple but powerful comparison utility. For full details, run man test
pe sistemul dumneavoastră, dar iată câteva utilizări și exemple tipice.
Test este cel mai adesea invocat indirect prin intermediul instrucțiunilor if
șiwhile
. Este, de asemenea, motivul pentru care veți întâmpina dificultăți dacă creați un program numit test
și încercați să îl rulați, deoarece acest builtin de shell va fi apelat în locul programului dumneavoastră!
Sintaxa pentru if...then...else...
este:
if then # if-codeelse # else-codefi
if ; then # do somethingfi
Puteți folosi și elif
, astfel:
if ; then echo "Something" elif ; then echo "Something else" else echo "None of the above"fi
Încercați următorul fragment de cod, înainte de a-l rula setați variabila X la diferite valori (încercați -1, 0, 1, hello, bye, etc). Puteți face acest lucru după cum urmează (mulțumiri lui Dave pentru că a semnalat necesitatea de a exporta variabila, așa cum s-a menționat înVariabile - Partea 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 ...
Încercați apoi din nou, cu $X
ca nume al unui fișier existent, cum ar fi /etc/hosts
.
test.sh
Rețineți că putem folosi punctul și virgula (;
) pentru a uni două linii. Acest lucru se face deseori pentru a economisi puțin spațiu în declarațiile simple if
.
Baza inversă (\
) are un scop similar, dar opus: îi spune shell-ului că acesta nu este sfârșitul liniei, ci că următoarea linie trebuie tratată ca parte a liniei curente. Acest lucru este util pentru lizibilitate. Se obișnuiește ca linia următoare să fie indentată după o backslash (\
) sau punct și virgulă (;
).
De exemplu, punctul și virgula (;
) este adesea folosit astfel pentru a uni cuvintele cheie if
și then
:
if ; then echo "X is a file which is newer than /etc/passwd"fi
în timp ce bara inversă (\
) este folosită pentru a împărți comanda pe o singură linie pe două linii în fișierul de script shell, în scopul lizibilității:
&& \ echo "X is a file which is newer than /etc/passwd"
După cum vedem din aceste exemple, test
poate efectua multe teste pe numere, șiruri de caractere și nume de fișiere.
Există un mod mai simplu de a scrie instrucțiunile if
: Comenzile &&
și ||
dau codul care trebuie executat dacă rezultatul este adevărat, respectiv fals.
Această sintaxă este posibilă deoarece există un fișier (sau un shell-builtin) numit construcția este recomandată pentru buclele while și verificările de igienă triviale cu care nu doriți să distrageți prea mult cititorul.
Rețineți că atunci când setați X la o valoare nenumerică, primele câteva comparații au ca rezultat mesajul:
Acest lucru se datorează faptului că comparațiile -lt, -gt, -le și -ge sunt concepute numai pentru numere întregi și nu funcționează pe șiruri de caractere. Comparațiile de șiruri de caractere, cum ar fi !=
, vor trata cu plăcere "5" ca un șir de caractere, dar nu există nici o modalitate rezonabilă de a trata "Hello" ca un număr întreg, astfel încât comparațiile întregi se plâng.
Dacă doriți ca scriptul dvs. shell să se comporte mai grațios, va trebui să verificați conținutulvariabilei înainte de a o testa - poate ceva de genul acesta:
În acest fel puteți echo
un mesaj mai semnificativ pentru utilizator și să ieșiți grațios. Variabila $?
este explicatăîn Variabile - Partea a II-a, iar grep
este o fiară complicată, așa că iată cum stă treaba: grep
găsește liniile de text care conțin cifre (0-9) și, eventual, alte caractere, așa că semnul de atenție (^
) din grep
găsește numai acele linii care nu sunt formate numai din numere. Putem lua apoi opusul (acționând asupra eșecului, nu asupra succesului). În regulă? >/dev/null 2>&1
direcționează orice ieșire sau eroare către dispozitivul special "null", în loc să meargă pe ecranul utilizatorului.
Mulțumesc mult lui Paul Schermerhorn pentru că m-a corectat - această pagină susținea că grep -v
ar funcționa, dar acest lucru este în mod clar mult prea simplist.
Putem folosi testul în buclele while, după cum urmează:
test2.sh
#!/bin/shX=0while do echo "Enter some text (RETURN to quit)" read X echo "You said: $X"done
Acest cod va continua să ceară date de intrare până când veți apăsa RETURN (X este de lungime zero).Mulțumesc lui Justin Heath pentru că mi-a semnalat că scriptul nu a funcționat - am omis ghilimelele din jurul lui $X în while
. Fără acele ghilimele, nu există nimic de testat când $X este gol.
Alexander Weber a semnalat că rularea acestui script se va încheia în mod dezordonat:
Acest lucru poate fi aranjat cu un alt test în cadrul buclei:
#!/bin/shX=0while do echo "Enter some text (RETURN to quit)" read X if ; then echo "You said: $X" fidone
Rețineți, de asemenea, că am folosit două sintaxe diferite pentru declarațiile if
pe această pagină. Acestea sunt:
if then echo "X is less than zero"fi.......... and ........if ; then echo "You said: $X"fi
Trebuie să aveți o pauză între instrucțiunea if
și construcția then
. Aceasta poate fi un punct și virgulă sau o linie nouă, nu contează care, dar trebuie să existe una sau alta între if
și then
.Ar fi frumos să se spună doar:
if echo "You said: $X"
dar then
și fi
sunt absolut necesare.
Înapoi: Bucle Următorul: Case