Köp denna handledning i skalskript som PDF för endast $5
Test används i praktiskt taget alla skalskript som skrivs. Det kanske inte verkar så, eftersomtest
inte ofta anropas direkt. test
kallas oftare som
if SPACE
Test is a simple but powerful comparison utility. For full details, run man test
på ditt system, men här är några användningsområden och typiska exempel.
Test anropas oftast indirekt via if
ochwhile
-anvisningarna. Det är också anledningen till att du får problem om du skapar ett program som heter test
och försöker köra det, eftersom detta inbyggda skal kommer att anropas istället för ditt program!
Syntaxen för if...then...else...
är:
if then # if-codeelse # else-codefi
if ; then # do somethingfi
Du kan också använda elif
, så här:
if ; then echo "Something" elif ; then echo "Something else" else echo "None of the above"fi
Prova följande kodutdrag, innan du kör det ställer du in variabeln X på olika värden (försök med -1, 0, 1, hello, bye, etc). Du kan göra detta på följande sätt (tack till Dave för att han påpekade behovet av att exportera variabeln, vilket noterades iVariabler - Del 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 ...
Prova sedan igen, med $X
som namnet på en befintlig fil, t.ex. /etc/hosts
.
.
test.sh
Bemärk att vi kan använda semikolonet (;
) för att sammanfoga två rader. Detta görs ofta för att spara lite utrymme i enkla if
-anvisningar.
Backslash (\
) har ett liknande, men motsatt syfte: det talar om för skalet att detta inte är slutet på raden, utan att följande rad ska behandlas som en del av den aktuella raden. Detta är användbart för läsbarheten. Det är vanligt att indela följande rad efter ett backslash (\
) eller semikolon (;
).
Till exempel används semikolonet (;
) ofta så här för att sammanfoga nyckelorden if
och then
:
if ; then echo "X is a file which is newer than /etc/passwd"fi
medans backslashet (\
) används för att dela upp kommandot med en enda rad på två rader i skalskriptfilen, för läsbarhetens skull:
&& \ echo "X is a file which is newer than /etc/passwd"
Som vi ser i dessa exempel kan test
utföra många tester på tal, strängar och filnamn.
Det finns ett enklare sätt att skriva if
-anvisningar: Kommandona &&
och ||
ger kod som skall köras om resultatet är sant respektive falskt.
Denna syntax är möjlig eftersom det finns en fil (eller shell-builtin) som heter konstruktionen rekommenderas för while-slingor och triviala sanitetskontroller som du inte vill distrahera läsaren alltför mycket med.
Notera att när du sätter X till ett icke-numeriskt värde resulterar de första jämförelserna i meddelandet:
Detta beror på att jämförelserna -lt, -gt, -le och -ge endast är utformade för heltal och inte fungerar på strängar. Strängjämförelser som !=
behandlar gärna ”5” som en sträng, men det finns inget vettigt sätt att behandla ”Hello” som ett heltal, så heltalsjämförelserna klagar.
Om du vill att ditt skalskript ska bete sig mer elegant måste du kontrollera innehållet i variabeln innan du testar den – kanske något liknande:
På detta sätt kan du echo
ge ett mer meningsfullt meddelande till användaren och avsluta på ett elegant sätt. Variabeln $?
förklaras i Variabler – Del II, och grep
är ett komplicerat djur, så här kommer det: grep
hittar rader av text som innehåller siffror (0-9) och eventuellt andra tecken, så att caret (^
) i grep
bara hittar de rader som inte bara består av siffror. Vi kan sedan ta det motsatta (genom att agera på misslyckande, inte på framgång). Okej? >/dev/null 2>&1
styr alloutput eller fel till den speciella ”null”-enheten, istället för att gå till användarens skärm.
Mycket tack till Paul Schermerhorn för att han rättade mig – den här sidan brukade hävda att grep -v
skulle fungera, men detta är uppenbarligen alldeles för förenklat.
Vi kan använda test i while-slingor enligt följande:
test2.sh
#!/bin/shX=0while do echo "Enter some text (RETURN to quit)" read X echo "You said: $X"done
Denna kod fortsätter att be om inmatning tills du trycker på RETURN (X är av noll längd).Tack till Justin Heath för att han påpekade att skriptet inte fungerade – jag hade missat citattecken runt $X i while
. Utan dessa citationstecken finns det inget att testa när $X är tomt.
Alexander Weber har påpekat att körning av detta skript kommer att sluta otidigt:
Detta kan snyggas upp med ett annat test inom slingan:
#!/bin/shX=0while do echo "Enter some text (RETURN to quit)" read X if ; then echo "You said: $X" fidone
Bemärk också att jag har använt två olika syntaxer för if
-anvisningar på den här sidan. Dessa är:
if then echo "X is less than zero"fi.......... and ........if ; then echo "You said: $X"fi
Du måste ha en paus mellan if
-anvisningen och then
-konstruktionen. Det kan vara ett semikolon eller en nyrad, det spelar ingen roll vilket, men det måste finnas ett eller annat mellan if
och then
.Det skulle vara trevligt att bara säga:
if echo "You said: $X"
men then
och fi
är absolut nödvändiga.
Back: Nästa: Case