Køb denne Shell Scripting Tutorial som PDF for kun $5
Test bruges af stort set alle shell-scripts, der er skrevet. Det ser måske ikke sådan ud, forditest
ikke ofte kaldes direkte. test
kaldes oftere som
if SPACE
Test is a simple but powerful comparison utility. For full details, run man test
på dit system, men her er nogle anvendelser og typiske eksempler.
Test påkaldes oftest indirekte via if
- ogwhile
-angivelserne. Det er også grunden til, at du vil komme i vanskeligheder, hvis du opretter et program kaldet test
og forsøger at køre det, da denne shell-buildin vil blive kaldt i stedet for ditprogram!
Syntaksen for if...then...else...
er:
if then # if-codeelse # else-codefi
if ; then # do somethingfi
Du kan også bruge elif
, som her:
if ; then echo "Something" elif ; then echo "Something else" else echo "None of the above"fi
Prøv følgende kodestykke, før du kører det sætter variablen X til forskellige værdier (prøv -1, 0, 1, hello, bye, osv.). Du kan gøre dette på følgende måde (tak til Dave for at gøre opmærksom på behovet for at eksportere variablen, som nævnt 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 ...
Prøv det så igen med $X
som navnet på en eksisterende fil, f.eks. /etc/hosts
.
.
test.sh
Bemærk, at vi kan bruge semikolonet (;
) til at samle to linjer. Dette gøres ofte for at spare lidt plads i simple if
-angivelser.
Backslash’en (\
) tjener et lignende, men modsat formål: den fortæller shell’en, at dette ikke er slutningen af linjen, men at den følgende linje skal behandles som en del af den aktuelle linje. Dette er nyttigt af hensyn til læsbarheden. Det er sædvanligt at indrykke den følgende linje efter en skråstreg (\
) eller et semikolon (;
).
For eksempel bruges semikolonet (;
) ofte på denne måde til at sammenføje nøgleordene if
og then
:
if ; then echo "X is a file which is newer than /etc/passwd"fi
hvorimod skråstregen (\
) bruges til at opdele den enlinjede kommando på to linjer i shellscriptfilen af hensyn til læsbarheden:
&& \ echo "X is a file which is newer than /etc/passwd"
Som vi kan se af disse eksempler, kan test
udføre mange tests på tal, strenge og filnavne.
Der findes en enklere måde at skrive if
-erklæringer på: Kommandoerne &&
og ||
giver kode, der skal køres, hvis resultatet er henholdsvis sandt eller falsk.
Denne syntaks er mulig, fordi der findes en fil (eller shell-builtin) kaldet konstruktionen anbefales til while sløjfer og trivielle sanitychecks, som man ikke ønsker at distrahere læseren for meget med.
Bemærk, at når du sætter X til en ikke-numerisk værdi, resulterer de første par sammenligninger i meddelelsen:
Dette skyldes, at sammenligningerne -lt, -gt, -le og -ge kun er designet til hele tal og ikke virker på strenge. Strengsammenligningerne, såsom !=
, behandler gerne “5” som en streng, men der er ingen fornuftig måde at behandle “Hello” som et heltal på, og derfor klager heltalsammenligningerne.
Hvis du vil have dit shell-script til at opføre sig mere elegant, skal du kontrollere indholdet af variablen, før du tester den – måske noget i stil med dette:
På denne måde kan du echo
give en mere meningsfuld besked til brugeren og afslutte på en elegant måde. Variablen $?
er forklaret i Variabler – Del II, og grep
er et kompliceret bæst, så her kommer den: grep
finder linjer af tekst, som indeholder tal (0-9) og muligvis andre tegn, så caret (^
) i grep
finder kun de linjer, som ikke kun består af tal. Vi kan så tage det modsatte (ved at handle på fiasko, ikke succes). Okay? >/dev/null 2>&1
leder ethvertoutput eller fejl til den særlige “null”-enhed, i stedet for at gå til brugerens skærm.
Meget tak til Paul Schermerhorn for at rette mig – denne side plejede at hævde, at grep -v
ville virke, men det er tydeligvis alt for forsimplet.
Vi kan bruge test i while-sløjfer som følger:
test2.sh
#!/bin/shX=0while do echo "Enter some text (RETURN to quit)" read X echo "You said: $X"done
Denne kode bliver ved med at bede om input, indtil du trykker på RETURN (X er nul længde).Tak til Justin Heath for at gøre opmærksom på, at scriptet ikke virkede – jeg havde glemt citationstegnene omkring $X i while
. Uden disse anførselstegn er der intet at teste, når $X er tomt.
Alexander Weber har gjort opmærksom på, at kørsel af dette script vil ende utidssvarende:
Dette kan ryddes op med en anden test inden for løkken:
#!/bin/shX=0while do echo "Enter some text (RETURN to quit)" read X if ; then echo "You said: $X" fidone
Bemærk også, at jeg har brugt to forskellige syntakser for if
-udsagn på denne side. Disse er:
if then echo "X is less than zero"fi.......... and ........if ; then echo "You said: $X"fi
Du skal have et brud mellem if
-erklæringen og then
-konstruktionen. Dette kan være et semikolon elleren newline, det er ligegyldigt hvilket, men der skal være det ene eller det andet mellem if
og then
.Det ville være rart bare at sige:
if echo "You said: $X"
men then
og fi
er absolut påkrævet.
Back: Sløjfer Næste: Case