Koop deze Shell Scripting Tutorial als PDF voor slechts $5
Test wordt door vrijwel elk geschreven shell script gebruikt. Dat lijkt misschien niet zo, omdattest
niet vaak direct wordt aangeroepen. test
wordt vaker aangeroepen als
if SPACE
Test is a simple but powerful comparison utility. For full details, run man test
op uw systeem, maar hier zijn enkele toepassingen en typische voorbeelden.
Test wordt het vaakst indirect aangeroepen via de if
enwhile
statements. Het is ook de reden dat u in de problemen komt als u een programma maakt met de naam test
en dat probeert uit te voeren, omdat deze shell builtin zal worden aangeroepen in plaats van uw programma!
De syntax voor if...then...else...
is:
if then # if-codeelse # else-codefi
if ; then # do somethingfi
U kunt ook de elif
gebruiken, zoals deze:
if ; then echo "Something" elif ; then echo "Something else" else echo "None of the above"fi
Probeer het volgende codefragment, voordat u het uitvoert, stel de variabele X in op verschillende waarden (probeer -1, 0, 1, hallo, doei, enz). Je kunt dit als volgt doen (met dank aan Dave voor het wijzen op de noodzaak om de variabele te exporteren, zoals opgemerkt inVariabelen - Deel 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 ...
Probeer het dan nog eens, met $X
als de naam van een bestaand bestand, zoals /etc/hosts
.
test.sh
Merk op dat we de puntkomma (;
) kunnen gebruiken om twee regels samen te voegen. Dit wordt vaak gedaan om een beetje ruimte te besparen in eenvoudige if
statements.
De backslash (\
) dient een soortgelijk, maar tegengesteld doel: het vertelt de shell dat dit niet het einde van de regel is, maar dat de volgende regel moet worden behandeld als onderdeel van de huidige regel. Dit is nuttig voor de leesbaarheid. Het is gebruikelijk om de volgende regel te laten inspringen na een backslash (\
) of puntkomma (;
).
De puntkomma (;
) wordt bijvoorbeeld vaak als volgt gebruikt om de trefwoorden if
en then
samen te voegen:
if ; then echo "X is a file which is newer than /etc/passwd"fi
, terwijl de backslash (\
) wordt gebruikt om het eenregelige commando over twee regels in het shellscriptbestand te verdelen, met het oog op de leesbaarheid:
&& \ echo "X is a file which is newer than /etc/passwd"
Zoals uit deze voorbeelden blijkt, kan test
veel tests uitvoeren op getallen, tekenreeksen en bestandsnamen.
Er is een eenvoudiger manier om if
verklaringen te schrijven: De &&
en ||
commando's geven code om uit te voeren als het resultaat respectievelijk waar of onwaar is.
Deze syntaxis is mogelijk omdat er een bestand (of shell-builtin) is genaamd constructie wordt aanbevolen voor while loops en triviale sanitychecks waarmee u de lezer niet te veel wilt afleiden.
Merk op dat wanneer u X op een niet-numerieke waarde zet, de eerste paar vergelijkingen resulteren in het bericht:
Dit komt omdat de -lt, -gt, -le en -ge vergelijkingen alleen zijn ontworpen voor gehele getallen, en niet werken op strings. De stringvergelijkingen, zoals !=
zullen "5" zonder problemen als een string behandelen, maar er is geen zinnige manier om "Hallo" als een integer te behandelen, dus de integer vergelijkingen klagen.
Als je wilt dat je shellscript zich eleganter gedraagt, moet je de inhoud van de variabele controleren voordat je hem test - misschien zoiets als dit:
Op deze manier kunt u echo
een zinvoller bericht aan de gebruiker geven, en op een nette manier afsluiten. De $?
variabele wordt uitgelegd in Variabelen - Deel II, en grep
is een ingewikkeld beest, dus hier gaat ie: grep
vindt tekstregels die cijfers (0-9) en mogelijk andere tekens bevatten, dus de caret (^
) in grep
vindt alleen die regels die niet alleen uit cijfers bestaan. We kunnen dan het omgekeerde nemen (door te handelen op mislukking, niet op succes). Oké? De >/dev/null 2>&1
stuurt eventuele output of fouten naar het speciale "null" apparaat, in plaats van naar het scherm van de gebruiker.
Met dank aan Paul Schermerhorn voor het corrigeren van mij - deze pagina beweerde voorheen dat grep -v
zou werken, maar dit is duidelijk veel te simplistisch.
We kunnen test in while-lussen als volgt gebruiken:
test2.sh
#!/bin/shX=0while do echo "Enter some text (RETURN to quit)" read X echo "You said: $X"done
Deze code blijft om invoer vragen totdat je op RETURN drukt (X is nul lengte).Met dank aan Justin Heath voor het erop wijzen dat het script niet werkte - ik had de aanhalingstekens rond $X in de while
over het hoofd gezien. Zonder die aanhalingstekens is er niets te testen als $X leeg is.
Alexander Weber heeft erop gewezen dat het uitvoeren van dit script rommelig zal eindigen:
Dit kan worden opgeruimd met een andere test binnen de lus:
#!/bin/shX=0while do echo "Enter some text (RETURN to quit)" read X if ; then echo "You said: $X" fidone
Merk ook op dat ik twee verschillende syntaxen heb gebruikt voor if
statements op deze pagina. Deze zijn:
if then echo "X is less than zero"fi.......... and ........if ; then echo "You said: $X"fi
U moet een pauze inlassen tussen het if
statement en het then
construct. Dit kan een puntkomma of een newline zijn, het maakt niet uit welke, maar er moet er een of een staan tussen de if
en de then
.Het zou mooi zijn om gewoon te zeggen:
if echo "You said: $X"
maar de then
en fi
zijn absoluut vereist.
Terug: Lussen Volgende: Case