Göm menyn

Mer skript

I det här steget går vi igenom olika skriptkommandon för flödeskontroll. Det finns ett fåtal reserverade ord som har speciell betydelse. De reserverade orden är if, then, elif, else, fi, do, while, until, for, case, esac, done, {, }. Dessa används framförallt för att styra programflödet i ett skript. Vi kommer att gå igenom de viktigaste av dem i den här delen. Observera att allt som sägs här gäller för skalet sh. Det är ett betydligt enklare skal än bash som lämpar sig för okomplicerade skript.

Villkorssatsen if

För att kunna styra exekveringen är det ofrånkomligt att man måste införa villkor av någon form. Vi går igenom några enkla villkorssatser som är fullt tillräckliga för de allra flesta syften.

if-satsen är den mest grundläggande styrkonstruktionen som finns att tillgå i skript och för den delen i alla programmeringsspråk och därför börjar vi med den. Den består av ett villkor, något som ska utföras om villkoret är sant och något som ska utföras om det inte är det. Syntaxen är enkel:

	
if test 
then 
	kommando1 
else 
	kommando2 
fi
	

Här kontrollerar vi om testet test var sant. I så fall utför vi kommando1, i annat fall kommando2. Testet innebär att man kontrollerar om kommandot test avslutades på ett korrekt sätt, dvs fick exitstatus 0. Vi kommer gå in lite mer på vad exitstatus är senare. För tillfället nöjer vi oss med att konstatera att om ett kommando utförs utan fel så får det exitstatus 0.

Vill man testa om på andra saker än om ett program avslutades på ett korrekt sätt ska man använda funktionen test, ja det finns faktiskt ett program som heter så. Det test gör är att testa om det villkor man ger det är sant. Det kan vara användbart om man vill testa om en variabel har ett visst värde eller om två variabler är lika.

	
#!/bin/sh 
if test -f minfil.txt 
then
	echo "Filen finns!"
else
	echo "Filen finns inte!"
fi
	

Ett annat, lite enklare, sätt att skriva samma test.

	
#!/bin/sh 
if [ -f minfil.txt ] 
then
	echo "Filen finns!"
else
	echo "Filen finns inte!"
fi  
	

Kom ihåg att de reserverade orden if, then och else måste stå först på en ny rad eller efter ett semikolon för att kännas igen. Den senare else-grenen i if-satsen kan utelämnas. Man kan också ha nästlade if-satser, dvs en if-sats inuti en annan.

Här är ytterligare ett exempel på hur man kan använda if-satsen i ett skript:

	
#!/bin/sh 
if last | grep -s petjo450 > /dev/null ; then 
	echo Peter har loggat in på den här datorn!
else 
	echo Peter har inte loggat in på den här datorn! 
fi
	

Kommandot last ger en lista över senaste inloggningar på den aktuella datorn. Vi skickar den listan vidare till grep som filtrerar ut alla rader som innehåller petjo450. Flaggan -s anger att kommandot inte ska mata ut något. Om en rad som matchar mönstret hittas så avslutas testet med exitstatus 0 och vi utför den första grenen i if-satsen. I annat fall utför vi den senare.

Övning Slå upp programmet test i manual- eller infosidorna. Ta sedan reda på hur man använder programmet för att testa om ett tal är större än ett annat. Lösningsförslag

Villkorssatsen case

case-satsen har en annan syntax än if-satsen och kan kännas mer naturlig att använda ibland. Syntaxen är:

	
case ord in 
mönster1) kommando1 
;; 
mönster2) kommando2 
;; 
mönsterN) kommandoN 
;; 
esac
	

Parametern ord jämförs med mönster1, mönster2 och så vidare i tills vi hittar en matchning. Då kommer de kommandon som står efter mönstret att köras. Varje klausul avslutas med två semikolon. Här är ett exempel:

	
#!/bin/sh 
case $1 in 
[A-Za-z]*) 
echo Argumentet börjar med en bokstav. 
;; 
[0-9]*) 
echo Argumentet börjar med en siffra. 
;; 
*) 
echo Argumentet börjar varken med bokstav eller siffra. 
;; 
esac
	

Parametern $1 motsvarar det första argumentet i anropet till skriptet. Det första mönstret matchar allt som börjar med en bokstav, dvs tecknen A-Z och a-z. Det andra mönstret matchar allt som börjar med en siffra. Asterisk matchar godtyckliga tecken.

Övning Skriv ett skript info.sh som tar ett argument. Beroende på om argumentet är "datum", "login" eller "katalog" skrivs dagens datum, vem som är inloggad eller aktuell katalog ut. Använd en case-sats. Lösningsförslag

Övning Här följer en lite svårare uppgift. Ladda ner och läs igenom skriptet elpe.sh . Skriptet skriver ut en given fil på den skrivaren som har kortast skrivarkö och ligger på samma våning. Studera skriptet och se om du hittar några oklarheter. Vad händer om man använder skriptet genom ThinLinc?

Upprepning med for

Precis som i vanlig programmering så finns det metoder för att kunna göra saker upprepade gånger vilket är absolut nödvändigt om man vill kunna utföra mer avancerade uppgifter. Vi ska här lite översiktligt gå in på vilka möjligheter man har.

for-satsen har följande syntax:

	
for variabel in lista-med-ord 
do 
kommando 
done
	

Detta innebär helt enkelt att man binder upp variabel till varje ord i lista-med-ord i tur och ordning och gör något som specificeras i kommando. Exempel:

	
#!/bin/sh 
# Se efter om ett antal användare (som anges som argument) har loggat in.
for i in $*
do
if last | grep -s $i
then
	echo $i har loggat in
else
	echo $i har inte loggat in
fi
done
	

Övning Prova exemplet ovan genom att kopiera in texten i valfri textredigerare och spara den. Glöm inte att göra skriptet körbart med chmod +x filnamn.

Övning Antag att du har fyra kataloger foo, bar, fie och gazonk. I var och en av dessa kataloger skapas automatiskt olika filer med ändelsen .log som du vill rensa bort med jämna mellanrum. Skriv ett skript som gör detta åt dig. Använd for-satsen. Lösningsförslag

Upprepning med while eller until

while- och until-satserna har följande syntax:

	
while kommando-lista1
do
kommando-lista2
done 

until kommando-lista1
do
kommando-lista2
done
	

Dessa båda konstruktioner är snarlika såtillvida att båda testar om det sista kommandot i kommando-lista1 returnerar ett giltigt värde eller inte (dvs exitstatus 0). I fallet med while fortsätter då loopen, medan until avbryter exekveringen ifall exitstatus är 0 för det sista kommandot. Exempel:

	
#!/bin/sh 
until last | grep -s $1 
do
sleep 60
done
echo "$1 har loggat in"
	

Detta skript kommer köras tills dess att den person som angivits som argument loggar in. Då kommer texten i sista raden att skrivas ut.

Referenser

The Grymoire - Home for Unix Wizards

Bra sida som innehåller det mesta man behöver veta för att skriva ett skript. Kan vara lite svår att förstå ibland. Innehåller en bra introduktion till reguljära uttryck.

Advanced Bash-Scripting Guide

Det mesta man behöver veta om bash, om man hellre vill skriva skript i bash.

Diagnos

Det finns ingen diagnos för detta avsnitt men det kan vara en bra idé att repetera och testa det som tas upp så att det sätter sig på minnet!


Sidansvarig: Peter Dalenius
Senast uppdaterad: 2023-08-21