Nieuws:

Welkom, Gast. Alsjeblieft inloggen of registreren.
Heb je de activerings-mail niet ontvangen?

Auteur Topic: Concept lesstof Bash scripting over: if, then, else, fi, ((...)), [[ ... ]]  (gelezen 2974 keer)

Offline laudaka

  • Lid
Later toegevoegd: Hoewel alles wat hieronder beschreven is wel werkt wordt in de meeste Bash scripts niet (( ... )) voor vergelijkingen met getallen gebruikt maar [ ... ] of soms ook [[ ... ]]. Best wel opmerkelijk omdat (( ... )) al sinds 1996 in Bash zit, maar het is dus niet gebruikelijk. Deze lesstof is dus niet zo goed als ik dacht toen ik het herschreef. Voor gevorderden is het wel interessant denk ik.

Hoi allemaal,
Bij ClubNix (Linux-gebruikers in Den Haag) zijn we bezig lesmateriaal te maken voor onze cursus Bash scripts schrijven. Misschien zijn er hier mensen die het leuk vinden om mee te denken? Van een bestaande HOW-TO voor beginners over Bash scripts schrijven heb ik nu één hoofdstuk helemaal herschreven. Het is een HOW-TO die op de website The Linux Documentation Project staat en die onder de GNU Free Documentation License valt. Het is dus open content en kan dus bewerkt en verder verspreid worden volgens de regels van de GNU Free Documentation License.

Hieronder de herschreven versie van hoofdstuk 6. Voorwaardelijke opdrachten. Het Nederlandse origineel staat hier: http://doets.xs4all.nl/HOWTO/HTML/nl/Bash-Prog-Intro-NL/Bash-Prog-Intro-HOWTO-NL.html . En het Engelse origineel staat hier op The Linux Documentation Project: http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO.html

Wat heb ik gebruikt als bronnen voor mijn wijzigingen? In de "Advanced Bash-Scripting Guide" op The Linux Documentation Project zijn heel veel details van Bash scripting uitgeplozen. En ik heb ook delen van de man page van Bash goed doorgelezen, helemaal onderaan staat welke delen precies.

Dit is trouwens gekopieerd uit een OpenOffice.org document en in dat document is de opmaak beter. Het staat hier: http://www.clubnix.net/forum/index.php?topic=556.0

Deze lesstof is bedoeld voor mensen met een redelijke voorkennis van Linux en met weinig of geen voorkennis van Bash shell scripts. Het is niet bedoeld voor mensen die een uitstekende kennis hebben van Linux en ook al redelijk Bash shell scripts kunnen schrijven. Daarom probeer ik per se te vermijden te vertellen dat je bij if...then...else...fi zoiets gebruikt als een exit status. Er zijn al genoeg moeilijke dingen en eigenaardigheden zonder dat te vertellen.

Bedankt aan iedereen die wil reageren. En heel erg bedankt als je verbeteringen hebt!

Oh en nog iets anders. Onze eerste les van de cursus Bash scripts schrijven bij ClubNix was een mislukking :'( Het was te moeilijk en we hadden gewoon geen goede lesstof. Dus vandaar dat we nu maar een al bestaande HOW-TO nog een stuk gaan verbeteren. En als je me nog goede boeken over Bash scripts schrijven kan aanraden: PB me :)

Veel plezier met Ubuntu,
Paulus/laudaka

Lesmateriaal Bash scripts schrijven, niveau C
6. Voorwaardelijke opdrachten
Dit hoofdstuk is herschreven door Paulus.

Voorwaardelijke opdrachten laten Bash een beslissing nemen of een actie wel of niet uitgevoerd zal worden. De beslissing wordt genomen door een voorwaarde te evalueren en te kijken of die voorwaarde wel waar of niet waar oplevert.

6.1 Droge Theorie
Voorwaardelijke opdrachten bestaan er in vele vormen. De basisvorm is: if voorwaarde then opdracht fi. Hierbij wordt opdracht alleen uitgevoerd wanneer de voorwaarde wel waar is. En het zal je niet verbazen dat de opdracht niet wordt uitgevoerd als de voorwaarde niet waar is.

“2 < 1” is een voorwaarde die niet waar oplevert, terwijl “2 > 1” een voorwaarde is die wel waar oplevert.

Er zijn uitgebreidere vormen van voorwaardelijke opdrachten, zoals: if voorwaarde then opdracht1 else opdracht2 fi. Hier wordt opdracht1 uitgevoerd als de voorwaarde wel waar oplevert, anders wordt opdracht2 uitgevoerd.

In een Bash script schrijf je het zo. Het inspringen, en het regeleinde na then zijn niet verplicht maar ik raad beginners van harte aan if-constructies op deze manier te schrijven:
if voorwaarde
then
    opdracht1
else
    opdracht2
fi

6.2 Voorbeeld: Voorwaardelijke opdracht if, then, fi met getallen
#!/bin/bash
if (( 2 > 1 ))
then
    echo "voorwaarde leverde op: wel waar."
fi


Zoals je ziet gebruik je bij getallen dubbele gewone haakjes (( ... )) om een voorwaarde te schrijven.

6.3 Voorbeeld: Voorwaardelijke opdracht if, then, fi met strings
#!/bin/bash
if [[ "Tux pinguin" == "Tux pinguin" ]]
then
    echo "Voorwaarde leverde op: wel waar."
fi

Zoals je ziet gebruik je bij strings dubbele vierkante haakjes [[ ... ]] om een voorwaarde te schrijven.

6.4 Voorbeeld: Voorwaardelijke opdracht if, then, else, fi
#!/bin/bash
if [[ "Tux pinguin" == "BSD duiveltje" ]]
then
   echo "Voorwaarde leverde op: wel waar."
else
   echo "Voorwaarde leverde op: niet waar."
   echo "Dat is geen verassing, dat de strings Tux pinguin"
   echo "en BSD duiveltje niet hetzelfde zijn!"
fi

Na de then en na de else mogen meerdere opdrachten staan.

6.5 Voorbeeld: Voorwaardelijke opdrachten met variabelen
#!/bin/bash
stad1="Apeldoorn"
stad2="Zaandam"
if [[ "$stad1" > "$stad2" ]]
then
   echo "Voorwaarde leverde op: wel waar."
else
   echo "Voorwaarde leverde op: niet waar."
fi

Dit ziet er op het eerste gezicht raar uit. Mag je bij strings ook kleiner dan (<) en groter dan (>) gebruiken? Ja, dat kan dus omdat Bash door de [[ ... ]] weet dat het om strings gaat. De strings worden dan vergeleken zoals je woorden in alfabetische volgorde sorteert, en niet zoals getallen vergeleken worden.

6.6 Overzicht van veelvoorkomende vergelijkingen in voorwaarden
Voorwaarden met getallenLevert waar op als
(( "$getal1" == "$getal2" ))getal1 is gelijk aan getal2
(( "$getal1" != "$getal2" ))getal1 is niet gelijk aan getal2
(( "$getal1" < "$getal2" ))getal1 is kleiner dan getal2
(( "$getal1" <= "$getal2" ))getal1 is kleiner dan óf gelijk aan getal2
(( "$getal1" > "$getal2" ))getal1 is groter dan getal2
(( "$getal1" >= "$getal2" ))getal1 is groter dan óf gelijk aan getal2

Voorwaarden met stringsLevert waar op als
[[ "$string1" == "$string2" ]]string1 is gelijk aan string2
[[ "$string1" != "$string2" ]]string1 is niet gelijk aan string2
[[ "$string1" < "$string2" ]]string1 komt alfabetisch eerder dan string2
[[ "$string1" > "$string2" ]]string1 komt alfabetisch later dan string2
[[ -z "$string1" ]]string1 is zero-length: hetzij string1 is leeg, hetzij string1 bestaat helemaal niet
[[ -n "$string1" ]]string1 is niet-zero-length: string1 bestaat en is niet leeg

6.7 Eigenaardigheden en adviezen
* Op sommige plaatsen op internet zul je in plaats van [[ string1 == string ]] het oudere [[ string1 = string ]] tegenkomen met één is-gelijk-teken. Ik raad om meerdere redenen af die variant te gebruiken. De beste reden om altijd een dubbel is-gelijk-teken te gebruiken is omdat het zo niet lijkt op de toekenning aan een variabele, dat gaat immers met var=inhoud.
* Het kan zijn dat je op internet in voorbeelden het oudere [ ... ] of test tegenkomt voor zowel getallen als strings. Ik raad je aan de twee nieuwere manieren te gebruiken met (( ... )) voor getallen en [[ ... ]] voor strings. Daar maak je minder snel fouten mee.
* De aanhalingstekens om variabelen heen zijn zelfs voor doorgewinterde programmeurs een eigenaardigheid van de Bash shell. Het zou meestal zonder aanhalingstekens kunnen. De reden dat het toch een goed idee is om de aanhalingstekens te gebruiken is dat Bash foutmeldingen kan geven als een variabele die in een voorwaarde staat leeg is.
* Voor de mensen van Niveau D die dit lezen: Als je gewend bent het oudere [ ... ] te gebruiken met -eq, -ne, -lt, -le, -gt, -ge dan raad ik je aan in ieder geval over te stappen naar [[ ... ]] als je toch niet (( ... )) wil gebruiken voor getallen. [[ ... ]] doet vrijwel altijd precies wat je bedoelt, de oudere vorm geeft soms onverwachte resultaten.

6.8 Meer lezen over voorwaardelijke opdrachten
Hoewel onderstaand hoofdstuk uit de "Advanced Bash-Scripting Guide" wel op Niveau D is en niet op Niveau C, staan er wel veel voorbeelden in die dingen een stuk duidelijker maken.
* Internetdocument: Cooper, Mendel. Advanced Bash-Scripting Guide. Website van The Linux Documentation Project, 2011. Chapter 7. Tests. http://tldp.org/LDP/abs/html/tests.html

Deze posting in dit topic is beschikbaar onder de GNU Free Documentation License. Kopiëren, wijzigen en/of verspreiden toegestaan op voorwaarde dat je je aan die licentie houdt. Auteur van deze posting: Paulus Santané (laudaka). Deze posting is een sterk gewijzigde versie van hoofdstuk 6 uit "BASH Programming - Introduction HOW-TO" op The Linux Documentation Project geschreven door Mike G. Vertaald onder de naam "BASH Programmering - Introductie HOW-TO" door Ellen Bokhorst.

N.B. Dit stuk hieronder is alleen bedoeld voor mensen die mee willen helpen de bovenstaande informatie te controleren. Want de man page van Bash is echt één van de man pages die een afrader is voor beginners en matig gevorderden.

Referenties Hoofdstuk 6. Voorwaardelijke opdrachten:
* man bash, kop SHELL GRAMMAR, subkop Compound Commands, paragraaf if list; then list; [ elif list; then list; ] ... [ else list; ] fi
* man bash, kop SHELL GRAMMAR, subkop Compound Commands, paragraaf ((expression))
* De constructie ((expression)) wordt geëvalueerd zoals omschreven in man bash, kop ARITHMETIC EVALUATION
* man bash, kop SHELL GRAMMAR, subkop Compound Commands, paragraaf [[ expression ]]
* De constructie [[ expression ]] wordt geëvalueerd zoals omschreven in man bash, kop CONDITIONAL EXPRESSIONS.
« Laatst bewerkt op: 2011/09/07, 23:45:55 door laudaka »