Ordet ''aritmetik'' betyder helt enkelt räkning. I detta avsnitt beskrivs det hur man kan utföra enklare beräkningar med hjälp av Bash.
Ett uttryck av formen $((formel))
skrivs om till det uträknade värdet av formel.
Formlerna som beräknas får bland annat innehålla
de fyra vanliga räknesätten, som skrivs med operatorerna
+ (addition), - (subtraktion),
* (multiplikation) och / (division).$ echo $((17+23))
40
$ mkdir Kapitel$((17+23))A
$ ls
Kapitel40A/ kopia.980217.bellman
bellman lenngren
$Ingen beräkning sker ifall tecknen $(( och )) utelämnas:$ echo 17+23
17+23
$Man får också använda variabler:$ x=17; y=23
$ echo $((x+y))
40
$Lägg märke till att man inte behöver skriva dollartecken
före variablernas namn när de som ovan förekommer i en beräkning.
Med hjälp av while kan man låta en variabel genomlöpa en följd av tal, som programmet loop nedan visar.
#!/bin/bash i=5 while [ $i -le 10 ] do echo "Nu har 'i' värdet $i" i=$((i+1)) done
Utskriften från loop ser ut så här:$ loop
Nu har 'i' värdet 5
Nu har 'i' värdet 6
Nu har 'i' värdet 7
Nu har 'i' värdet 8
Nu har 'i' värdet 9
Nu har 'i' värdet 10
$
Multiplikationen i formeln
2+3*4
utförs före additionen eftersom
det är en konvention att multiplikation och division
har högre prioritet än addition och subtraktion.
Om man vill att additionen ska utföras först måste man ange parenteser,
(2+3)*4=20.$ echo Man räknar lätt ut att 2+3*4=$((2+3*4))
Man räknar lätt ut att 2+3*4=14
$ echo $(( (2+3)*4 ))
20
$
En förteckning av de operatorer som kan användas vid beräkningar i Bash ges i tabell 11.6. Operatorerna är grupperade i prioritetsordning.
Bash räknar bara med heltal.
Detta innebär i synnerhet att om resultatet vid en division inte
går jämnt ut, så stryks decimalerna från svaret.
Till exempel gäller i Bash att 13/5 är lika med 2.
Om 13 hästar ska delas ut till fem systrar,
så får systrarna två hästar var.
Kvoten är därmed 2. Det blir tre hästar över,
och man säger att resten
(dvs det antal som blev över) är 3.$ echo $(( 13/5 ))
2
$Resten vid en division kan beräknas med hjälp av operatorn %.$ echo $(( 13%5 ))
3
$
Bash kan bara hantera heltal av en begränsad storlek;
vanligtvis får talen ha högst
9-10 siffror om resultatet ska bli rätt.$ echo $(( 1000*1000 ))
1000000
$ echo $(( 1000000*1000000 ))
-727379968
$Det korrekta resultatet vid den andra beräkningen
ovan är ett tal med 13 siffror,
men eftersom Bash (på min dator) inte kan hantera så stora tal
gavs ett fullständigt felaktigt resultat.
Om man omger ett heltal med tecknen (( respektive )),
så undersöker Bash ifall talet är skilt från noll. Lyckad slutstatus
anger att talet var skilt
från noll, misslyckad slutstatus att talet var lika med noll.$ (( 5 ))
$ echo $?
0
$ (( 2*3-6 ))
$ echo $?
1
$ Som vi snart ska se kan detta användas som ett
alternativ till kommandot test vid jämförelser av heltal.
|
Tabell 11.7 visar hur man kan jämföra två heltal i Bash.
Lägg särskilt märke till att likhet skrivs med två
likhetstecken eftersom det annars skulle bli en tilldelning.
Resultatet av en jämförelse är ett heltal,
nämligen 1 (som betyder ''sant'') ifall
jämförelsen var uppfylld, annars 0 (dvs ''falskt'').
Jämförelsen a==b betraktas alltså som en beräkning vars värde
är 1 ifall a=b;
värdet är 0 om
.$ echo $(( 5>3 ))
1
$ echo $(( 2*4>=9 ))
0
$ Om man utelämnar dollartecknen ovan, så får man tester i stället för
beräkningar:$ if (( 1+1==2 )) ; then echo 'Bash kan räkna!' ; fi
Bash kan räkna!
$
Variabeln RANDOM, som är inbyggd i Bash, ger ett slumptal
mellan 0 och 32767.$ echo $RANDOM
12281
$ echo $RANDOM
31550
$ echo $RANDOM
3487
$ Om vi vill ha ett slumptal mellan tex 0 och 100,
så kan vi först låta Bash ge oss ett slumptal
mellan 0 och 32767, och sedan ta resten vid division
av detta tal med 101:$ echo $(( $RANDOM%101 ))
37
$ För att simulera ett tärningskast behöver vi
ett slumptal mellan 1 och 6. Vi beräknar då först
ett slumptal mellan 0 och 5, och adderar sedan 1 till detta:$ echo $(( $RANDOM%6+1 ))
4
$ Programmet räkna nedan
beräknar två slumptal mellan 1 och 10. Programmet
frågar efter summan, och det ger sig inte förrän
man har svarat rätt.
#!/bin/bash TAL1=$(( $RANDOM%10+1 )) TAL2=$(( $RANDOM%10+1 )) read -p "Vad är $TAL1+$TAL2? " SVAR until (( SVAR == TAL1+TAL2 )) do echo 'Fel fel fel!' read -p "Ange $TAL1+$TAL2 igen: " SVAR done echo 'Rätt svar!'
Om det svar man matar in är fel, så
skrivs texten ''Fel fel fel!'' ut, och
man får sedan göra ett nytt försök.$ räkna
Vad är 5+7? 8
Fel fel fel!
Ange 5+7 igen: 12
Rätt svar!
$ räkna
Vad är 1+1? 2
Rätt svar!
$ Vid den andra körningen fick vi ett lätt problem,
1+1, och lyckades därmed svara rätt första gången.
Därför kördes aldrig kommandona mellan
do och done.
Instruktionen declare -i namn anger att
variabeln namn är ett heltal. Fördelen med detta
är att värdet av namn då beräknas automatiskt, dvs
även om tecknen $(( och )) utelämnas.
I följande program, som visar ännu ett sätt att låta en heltalsvariabel
genomlöpa ett antal värden, har en variabel markerats som heltal:
#!/bin/bash declare -i tal=1 echo -n 'Några tal:' while (( tal<=10 )) ; do echo -n " $tal" tal=tal+1 done echo '.'
Utskriften från programmet blir
Några tal: 1 2 3 4 5 6 7 8 9 10.
Operatorn += är en kombination av addition och tilldelning. Till exempel har a+=3 värdet a+3, och som en sidoeffekt av beräkningen a+=3 får a värdet a+3. Operatorerna -=, *= osv fungerar på motsvarande sätt. Programmet ovan kan alltså skrivas så här istället:
#!/bin/bash declare -i tal=0 echo -n 'Några tal:' while (( (tal+=1)<=10 )) ; do echo -n " $tal" done echo '.'
Oftast är den förra versionen av programmet att föredra eftersom den senare versionen är mer svårläst.