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
- Villkorssatsen case
- Upprepning med for
- Upprepning med while eller until
- Sammanfattning och diagnos
- Referenser
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: 2024-08-26