next up previous contents
Nästa: 11.2 Upprepningar Upp: 11. Grundläggande Bashprogrammering Förra: 11. Grundläggande Bashprogrammering

11.1 Villkor

När ett program kört färdigt berättar det ifall körningen var lyckad eller misslyckad. Vad det innebär att körningen lyckats varierar från program till program, men oftast innebär ett misslyckande att någon form av fel uppstått. Så hur fungerar det hela? Jo, programmet lämnar ifrån sig ett tal, som kallas dess slutstatus, då det avslutas. Om talet är 0, så anses körningen vara lyckad. Om talet är större än 0, så anses körningen ha misslyckats. Tex kan slutstatus 1 markera en viss typ av fel och slutstatus 2 ett annat slags fel.

I Bash anger parametern ? slutstatus för det senaste kommandot man gett.$ rm kopia.980217.bellmna
rm: kopia.980217.bellmna: Filen eller katalogen finns inte
$ echo $?
1
$ rm kopia.980217.bellman
$ echo $?
0
$
Vid första rm-kommandot ovan uppstod ett fel, och slutstatus var 1. Nästa gång gick det bra, och slutstatus var 0.

Kommandot exit 0 avslutar ett Bashprogram med slutstatus 0. För att ge slutstatus 1 skriver man i stället exit 1 osv. Om siffran utelämnas, så avslutas programmet med samma slutstatus som det senast utförda kommandot.

Kommandot test kan undersöka olika slags villkor. Om villkoret är uppfyllt lämnar test slutstatus 0, annars lämnas slutstatus 1. Tex kontrollerar test 5 -gt 7 ifall 5>7. Här står -gt för ''greater than'' (se tabell 11.4). Som synonym för test kan man använda tecknet [, och då skriver man [ 5 -gt 7 ] istället.$ test 5 -gt 7
$ echo $?
1
$ test 7 -gt 5
$ echo $?
0
$ [ 1 -gt -2 ]
$ echo $?
0
$
Detta innebär att villkoren 7>5 och 1>-2 är uppfyllda, men inte 5>7.

Med hjälp av en if-sats kan man få ett program att vidta olika åtgärder beroende på om ett villkor är uppfyllt eller inte. Syntaxen är

if testkommando
then kommando
fi
Först körs testkommando. Om det lyckades (dvs om det har slutstatus 0) så utförs kommandot kommando. Man kan ha fler radbrytningar om man vill, Bash vet att kommandot inte är komplett förrän man skrivit fi. Det är också möjligt att skriva kommandot på en rad, men då måste man använda semikolon i stället för radbrytning.$ if [ 5 -gt 7 ] ; then echo Hej ; fi
$ if [ 7 -gt 5 ] ; then echo Hej ; fi
Hej
$
I det första fallet ovan var testkommandot lyckat, i det andra fallet var det misslyckat. Kommandot echo Hej utfördes bara i det andra fallet.

Om man vill, så kan man ha raden ''else alternativkommando'' före fi ovan; i så fall utförs alternativkommando ifall testkommandot misslyckades. Dvs if kan användas så här också:

if testkommando
then kommando
else alternativkommando
fi

Vi ändrar vårt program argument till följande:

#!/bin/bash
echo "Totalt $# argument."
if [ $# -gt 12 ] ; then
  echo "Det trettonde argumentet är ${13}."
else
  echo "Det finns inget trettonde argument." 1>&2
  exit 1
fi

Om antalet argument är större än 12, så skrivs det trettonde argumentet ut. Annars skrivs ett felmeddelande ut och programmet avslutas med slutstatus 1.$ argument a b c d e f g h i j k l m n o p q r
Totalt 18 argument.
Det trettonde argumentet är m.
$ echo $?
0
$ argument esike desike luntan tuntan
Totalt 4 argument.
Det finns inget trettonde argument.
$ echo $?
1
$

I tabellerna 11.1, 11.2, 11.3, 11.4 och 11.5 ges en förteckning av de viktigaste testerna som test eller [ kan utföra.

 
Tabell 11.1: Test av filtyp
 
Sats Uppfylld om...
-e fil fil existerar
-f fil fil existerar och är en vanlig fil
-d fil fil existerar och är en katalog
-L fil fil existerar och är en symbolisk länk
-b fil fil existerar och är en blockspecialfil
-c fil fil existerar och är en teckenspecialfil
-p fil fil existerar och är en FIFO
-S fil fil existerar och är en socket


 
Tabell 11.2: Test av filattribut
 
Sats Uppfylld om...
-r fil fil existerar och är läsbar
-w fil fil existerar och är skrivbar
-x fil fil existerar och är exekverbar
-u fil fil existerar och är setuid
-g fil fil existerar och är setgid
-g fil fil existerar och har fastbiten satt
-s fil fil existerar och är icke-tom
fil1 -nt fil2 fil1 är nyare än fil2 med avseende på senaste ändring
fil1 -ot fil2 fil1 är äldre än fil2 med avseende på senaste ändring


 
Tabell: Tester på textsträngar
 
Sats Uppfylld om...
-z sträng längden av sträng är noll
-n sträng längden av sträng inte är noll
sträng längden av sträng inte är noll
sträng1 = sträng2 sträng1 är identisk med sträng2
sträng1 != sträng2 sträng1 inte är identisk med sträng2
sträng1 < sträng2 sträng1 kommer före sträng2 i bokstavsordning
sträng1 > sträng2 sträng1 kommer efter sträng2 i bokstavsordning


 
Tabell: Tester på heltal
 
Sats Uppfylld om...
tal1 -eq tal2 tal1 är lika med tal2
tal1 -ne tal2 tal1 inte är lika med tal2
tal1 -lt tal2 tal1 är mindre än tal2
tal1 -gt tal2 tal1 är större än tal2
tal1 -le tal2 tal1 är mindre än eller lika med tal2
tal1 -ge tal2 tal1 är större än eller lika med tal2


 
Tabell: Tester på villkorssatser
 
Sats Uppfylld om...
! sats sats inte är uppfylld
sats1 -a sats2 sats1 och sats2 är uppfyllda
sats1 -o sats2 sats1 och/eller sats2 är uppfylld

Bash kan skilja mellan olika fall beroende på värdet av en variabel med hjälp av kommandot case. Programmet genus nedan ger ett exempel.

#!/bin/bash
case $1 in
  Anna | Eva | Åsa) echo "$1 är en kvinna." ;;
  Kalle | Nisse | Pelle) echo "$1 är en man." ;;
  * ) echo "Jag vet inte huruvida $1 är en kvinna eller en man." ;;
esac

Så här fungerar programmet:$ genus Eva
Eva är en kvinna.
$ genus Nisse
Nisse är en man.
$ genus Sofia
Jag vet inte huruvida Sofia är en kvinna eller en man.
$
Syntaxen för kommandot case är

case ord in
val | val ...| val ) kommandon ;;
val | val ...| val ) kommandon ;;
...
esac
Mellan case och esac (som är ''case'' baklänges, liksom ''fi'' är ''if'' baklänges) anges ett eller flera fall, separerade av dubbla semikolon. I varje sådant fall får man ange ett eller flera val, separerade av lodräta streck, samt därefter en högerparentes och ett godtyckligt antal kommandon som ska utföras ifall ord är något av dessa val. Bara kommandona från det första fallet där ord förekommer utförs. Liksom filnamn får valen innehålla jokertecken. Det är därför som valet * i programmet genus matchar allt som inte matchas av något av de andra valen.


next up previous contents
Nästa: 11.2 Upprepningar Upp: 11. Grundläggande Bashprogrammering Förra: 11. Grundläggande Bashprogrammering
Goran Andersson
1999-03-08