Linux Bash Scripting

Een Linux Script is niet meer dan een verzameling commandos die je in één bestandje zet om uit te voeren. Het doet misschien nog wel het meeste denken aan een 'batchfile' in DOS (voor diegenen die nog weten wat dat is...). Een script is razendsnel en kan veel werk uit handen nemen, dus het is de moeite waard om je er eens in te verdiepen, tenminste als je met Linux werkt.

Index

Wat informatie over cross-platform scripts.

Bash scripting is 'Linux only' dus je kan bijvoorbeeld je scripts niet naar Windows exporteren of zo. Wil je binnen Linux software schrijven die cross platform is (dwz software die je kunt maken voor Linux, Windows en Mac) kun je je beter richten op software in de programmeertaal C schrijven. Er zijn handige tools beschikbaar om met een korte leercurve cross-platform software te maken zoals Bacon, FreeBasic en de Harbour Compiler.

Open de Terminal

De Terminal in linux is een beetje hetzelfde als de DOS prompt van vroeger: een prompt met een knipperend cursortje erachter. Het 'icon' om dit te starten ziet er altijd zo'n beetje uit als het plaatje hier rechts.

Een simpel script

Een script in zijn simpelste vorm ziet er zo uit:

#!/bin/bash
echo "Hallo"

De bovenste regel die begint met !# geeft aan welke bash er gebruikt wordt., het kan namelijk zijn dat jouw Linux distributie een andere bash gebruikt. Je kan uitvinden welke bash jij gebruikt met:

which bash

Een script uitvoeren in Linux

Als wij bovenstaand script opslaan in een bestand genaamd hallo.sh kun je het uitvoeren door in te typen:

./hallo.sh
Hoppakkee! Uh nee, je krijgt een foutmelding Toegang geweigerd! Hier komt de (terecht strenge) veiligheid van Linux om de hoek kijken. Je moet dit bestandje 'uitvoerbaar' maken of 'executable'. Je kan dit doen door in te typen:
chmod +x hallo.sh
Probeer het nu nog een keer en je script wordt netjes uitgevoerd. Je kan overigens ook in je bestandsbeheerder op de rechtermuisknop klikken en daarna op Eigenschappen, je kan daar ook de rechten veranderen op een wat makkelijkere manier.

Druk eens op je toetsenbord op de Pijltje naar boven-toets: je vorige commando verschijnt weer! Bespaart je een hoop typewerk. Je kan al je commandos trouwens ook bekijken met history.

Het zoekpad van je systeem $PATH

Kijk eens met pwd in welke directory je je nu bevindt. Het script wat je uitvoert bevindt zich ook hier ook in. Maar misschien wil je je scripts in een andere directory onderbrengen en dat je systeem ze altijd kan 'vinden'. Je kan dit doen met $PATH.

Je kan zien wat je zoekpad is met echo $PATH. Je kan (tijdelijk) de directory met scripts toevoegen met export PATH=$PATH:/home/caspar/scripts. Let wel even op dat dit extra zoekpad verdwenen is de volgende keer dat je je computer opstart. Ja lekker handig! Dan is het weer weg! Hoe je een directory permanent aan je systeem-zoekpad kunt toevoegen dat mag je zelf gaan uitzoeken. Kijk even welke Linux distributie je gebruikt of waar jouw distributie op is gebaseerd. Dit is meestal Ubuntu of Debian. Google vervolgens eens ubuntu how to change path permanently. En ga maar aan de slag.

Variabelen en constanten

#
#Gebruik geen spaties wanneer je variabelen maakt.
#
wie="Caspar" #goed
wie = "Caspar" #fout
wie = 'Caspar' #ook fout
#
#Een variabele wordt gedeclareerd zonder $, maar als je hem gebruikt gebruik je $ weer wel.
#
wie="Caspar"
echo "Hallo, $wie!"
#
#Je kan ook variabelen meegeven direct achter de opdracht.
#
cp $1 $2
#
#Constanten declareer je met een :
#
: ${KEY_OK=0}
: ${KEY_CANCEL=1}
: ${KEY_ESC=255}
echo "OK heeft de waarde:" $KEY_OK

Strings

#
#Een simpele zin hoeft niet omsloten te worden met dubbele aanhalingstekens.
#
echo Dit is een zinnetje
#
#Wil je echter wel aanhalingstekens gebruiken, zet dan de zin wel tussen aanhalingstekens.
#
echo "Dit is wat 'tekst'"
#
#Wil je dan een deel op een nieuwe regel begint, gebruik dan -e en \n
#
echo -e "Dit is een regel... \nEn deze tekst begint op een nieuwe regel...."
#
#Substring (positie, lengte). Het volgende commando geeft de eerste drie karakters vanaf links.
#
${naam:0:3}
#
#Substring vanaf rechts
#
${naam:(-3):3}

Commentaar in je script

#Dit is wat commentaar op één regel
: '
Dit is 
commentaar
op meerdere regels
'

Uitvoeren van shell-commandos in je script

Zoals je misschien al weet kent Linux een enorme hoop commandos die je kunt uitvoeren in de Terminal. Echte Linux-freaks hebben zelfs geen grafische omgeving, maar dan moet je wel dag in - dag uit met je kop in de code zitten voor een paar jaar, en daar moet je maar net zin in hebben.

Je kan uiteraard zo'n shell-commando in je script gebruiken. Zo wordt hieronder whoami gebruikt:

echo "Hallo, $(whoami)!"

Gebruikers input

We kunnen natuurlijk ook vragen of een gebruiker wat intypt, dit doe je met read:

#!/bin/bash
echo "Hallo, hoe heet jij?"
read wie
echo "Hallo, $wie!"

Dialog

Natuurlijk zal je meer nodig hebben als je een programma schrijft om te communiceren met de gebruiker. Denk maar aan invulformulieren of een ja/nee bevestiging. Dit kan met Dialog. Dialog zit al bij de meeste linux distributies en heeft een zeer uitgebreide documentatie, en dat is ook nodig want het heeft meer dan 100 opties die je kunt meegeven. Hieronder een bloemlezing.

Als Dialog is geïnstalleerd dan kun je heel veel voorbeelden vinden in /usr/share/doc/dialog/

Dialog opties

Parameter Omschrijving
--buildlist Twee lijsten naast elkaar. De lijst links bevat niet geselecteerde items, de rechter wel geselecteerde items. De gebruiker kan de cursor tussen de lijsten bewegen.
--calendar Toont een kalender en de gebruiker kan een datum kiezen.
--checklist Een lijst waarvan de gebruiker één of meerdere keuzes kan maken.
--dselect Een directory selecteren.
--editbox Een simpele textfile-editor.
--form Een formulier met verschillende invulvelden.
--fselect Selecteer een bestand.
--gauge Een balk die aangeeft hoever een proces is.
--infobox Toont een bericht (eventueel met pauze) en verdwijnt weer netjes.
--inputbox Een invulveld wat ingevuld kan worden.
--menubox Een lijst met keuzes.
--msgbox Toont een bericht en wacht op antwoord van de gebruiker.
--passwordbox Hetzelfde als --inputbox, maar er wordt niks van de invoer op het scherm getoond.
--pause Een bericht en een timer. Het bericht verwijnt als de timer op nul is of als de gebruiker op 'Ok' of 'Cancel' heeft geklikt.
--radiolist Een lijst met keuzes en de gebruiker kan er één kiezen.
--rangebox De gebruiker kan een waarde kiezen met een 'slider'.
--tailbox Toont een text die 'real-time' wordt aangevuld. Werkt hetzelfde als tail -f.
--textbox Een simpele textbestand-viewer. Gebruikt veel van dezelfde toetsencombinaties als bij less.
--timebox Invoer van tijd.
--yesno Toont een bericht en je kan Yes/No aangeven.

Voorbeeld van een Dialog script

#!/bin/sh
dialog --backtitle "Graai BV" \
	--title "RADIOLIST BOX" --clear "$@" \
        --radiolist "Hallo, dit is een radiolist box. Je kan dit gebruiken 
om de gebruiker een lijst met keuzes te geven die aan- of uitgezet kunnen worden. \n\
Zet een selectie aan of uit met de spatiebalk.\n\n\
Welke films vind je leuk?" 20 61 5 \
"Star Wars"  "Omslachtig gedoe in de ruimte." off \
"Forrest Gump"    "Tom Hanks jeweetwel." ON \
"Sleepy Hollow" "Gothic sprookje met Jack Sparrow." off

Goh Caspar, fijn hoor die gare menus in je terminal... dat wil ik niet ik wil vette grafische shizzle! Ja, dat snap ik. Maar zorg nu eerst maar eens dat je iets van de grond krijgt en ga daarna nog eens werken aan het uiterlijk. En bedenk bovendien dat het grafische deel van je systeem veel systeemkracht opslurpt.

Ik vind dat je als programmeur ook moet kunnen werken zonder al die grafische jibberish. En dat je je systeem en dus je computer van voor tot achter moet leren kennen. En daar ben je hier mee bezig, niet met de boel mooi aankleden. Maar goed, kijk eens even naar naar het pakket Zenity, dit zijn hetzelfde soort menus als Dialog, maar dan de grafische variant.

Waardes vergelijken

Vergelijken van numerieke waardes Vergelijken van strings Wat doet het
-eq == Is gelijk aan
-ne != Is niet gelijk aan
-gt > Groter dan
-ge >= Groter dan of gelijk
-lt < Kleiner dan
-le <= Gelijk of kleiner dan

if..then.else

#!/bin/bash
echo 'Hoe oud ben je?'
read leeftijd
if [ $leeftijd -gt 18 ] ;
then
    echo 'Je mag bier drinken.'
else
    echo 'Je mag geen bier drinken.'
fi

while loop

#!/bin/bash
doorgaan=true
teller=1
while [ $doorgaan ]
    do
    echo $teller
    if [ $teller -eq 5 ]; #let hier even op de ; na if
    then
	break
    fi
    ((teller++))
done

En hier was de tijd op! Binnenkort hier meer.