Linux-Kurs: bash-Skripte
bash-Skripte sind eine schöne Sache um immer wieder kommende Befehle zu automatisieren. Wir hatten im letzen Teil des Kurses schon ein kleines Skript: "piep".
Es diente dazu, bei Eintritt und Verlassen des Runlevels kurz mal zu piepen.
Ein bash-Skript ist quasi eine Batch-Datei unter DOS, aber leistungsfähiger ;-)). Unter Windows ist es mit der PowerShell vergleichbar.
Hallo Tux
Ok, fangen wir mal an, mit dem üblichen "Hallo,Tux" Programm (oder so):
- Zuerst schreibst du mit einem beliebigen Text-Editor die Datei "hallo.sh". Die hat diesen Inhalt:
- Damit du dein Skript auch ausführen kannst mußt du erst noch schnell die Rechte ändern:
|
[tux]$ chmod u+x hallo.sh
|
- Und nun die Datei im aktuellen Verzeichnis ausführen:
[tux]$ ./hallo.sh
Hallo Tux!
|
Das war es schon. Auf deinem Monitor solltest du nun "Hallo Tux!" sehen.
Jetz mit etwas mehr Anspruch:
#!/bin/bash
#Programm hallo2.sh
echo "Wie heißt du ?"
read Name
echo "Hallo $Name"
|
In der ersten Zeile sagst du der bash, dass dieses Skript von /bin/bash ausgeführt werden soll. Das ist eigentlich nicht umbedingt nötig, aber eleganter und kann Fehler vermeiden helfen.
In der zweiten Zeile steht ein Kommentar, dass siehst du an dem "#", dieses leitet fast immer einen Kommentar. Warum fast immer ?
Na guck noch mal in die erste Zeile, was es dort im Zusammenhang mit dem "!" heißt ...
In der dritten Zeile geben wie einen einfachen Text aus, und in der vierten Zeile lesen wir mit "read" eine Variable (ein Variable ist eine Art Speicher) ein, hier "Name".
In der letzen Zeile geben wir das Hallo mit dem eben eingegebenen Namen aus. Wird vor einer Variablen ein "$" geschrieben, wird der Inhalt der Variable ausgeben, und das ist der Name den du eben eingehämmert hast.
Parameterübergabe
Jetzt schreiben wir ein Programm, das direkt Parameter beim Kommandoaufruf benutzt.
Erst mal das Programm:
#!/bin/bash
#Programm hallo3.sh
echo "Hallo $1"
|
Dieses Programm rufst du nun so auf:
[tux]$ ./hallo.sh vorname
Hallo vorname
|
wobei vorname natürlich dein Vorname ist ...
Darauf sollte dein Programm "Hallo vorname" ausgeben.
If-Else Anweisung
Eine If-Else Anweisung läßt sich ungefähr mit "Wenn ... dann" übersetzen.
Hier siehst du schon wofür du diese brauchst:
Du kannst einfach auf bestimmte Dinge abfragen.
Am klarsten wird das an einem Beispiel-Programm :
#!/bin/bash
#Programm if.sh
if [ "$1" = "tux" ]; then
echo "Hallo Pinguin"
#Wenn der erste Parameter tux ist, schreibe Hallo Pinguin
else
echo "Hallo $1"
#Sonst schreibe Hallo Parameter
fi
exit 0
|
Einfach mal ausprobieren mit:
[tux]$ ./if.sh tux
Hallo Pinguin
|
und danach:
[tux]$ ./if.sh markus
Hallo markus
|
Damit ist die If-Else Anweisung klar, oder?
Und jetzt mal die Syntax:
Die gesamte If-Else Anweisung beginnt mit dem if und endet mit fi (fi = if umgedreht). Alles dazwischen gehört zur If-Abfrage.
Die wichtigste Zeile:
if [ "$1" = "tux" ]; then
Hier sagst du:
Wenn (if) der erste Parameter ("$1") gleich (=) Tux ("tux") ist, dann (then)...
Danach schreibst du was passieren soll wenn die Anweisung zutrifft ( echo "Hallo Pinguin").
Ab der Zeile mit else steht was passieren soll, wenn if nicht paßt (echo "Hallo $1").
In der letzen Zeile steht ein exit 0. Damit übergibst du dem nachfolgenden Programm einen sogenannten Rückgabe-Parameter. Damit kannst du dem nachfolgenden Programm anzeigen, ob das Skript erfolgreich beendet wurde oder ein Fehler aufgetreten ist. Übrigens, viele Unix/Linux-Programme nutzen diese Option.
Achtung!! Die Syntax der If-Else Anweisung muß genauso geschrieben werden (die Leerzeichen sind EXTREM wichtig !), sonst geht deine If-Abfrage nicht.
Noch ein Tipp: Willst du Zahlen vergleichen mit == , >= , < ; mußt
du -eq (== equal), -ge (>= greater equal), lt (< less than) nehmen.
Case Anweisung
If-Else ist ja ganz nett, aber wenn du auf mehrere verschieden Parameter abfragen willst, wird es schon etwas komplexer. Hier hilft dir die Case Anweisung.
Man kann sie so beschreiben: Wenn 1 dann das, Wenn 2 dann dieses, Wenn 3 dann dasda, Wenn nichts davon dann...
Auch hier wieder ein erklärendes Beispiel:
#!/bin/bash
#Programm case.sh
case "$1" in
tux)
echo "Hallo Pinguin"
#Wenn Parameter 1 = tux
;;
markus)
echo "Hallo, alter Sack ;-)"
#Wenn Parameter 1 = markus
;;
*)
echo "Hast du keinen richtigen Namen ? ;-)"
#Wenn vorher nichts passte
;;
esac
exit 0
|
Einfach mal ausprobieren mit:
[tux]$ ./case.sh tux
Hallo Pinguin
|
und dann:
[tux]$ ./case.sh markus
Hallo, alter Sack ;-)
|
und danach:
[tux]$ ./case.sh dave
Hast du keinen richtigen Namen ? ;-) |
Eigentlich ist die damit Syntaxschon fast klar:
Zuerst sagt du worauf die Case-Anweisung reagieren soll: Hier auf Parameter 1 also case "$1" in.
Danach wird der Reihe nach abgeklappert ob eine Bedingung paßt. Unsere erste Anweisung beschreibe ich mal genauer:
Zuerst steht in der Anweisung : tux), und das heißt: wenn der erste Parameter "tux" ist,
dann schreibe "Hallo Pinguin" (echo "Hallo Pinguin").
Wichtig ist die Anweisung mit " ;; " abzuschließen !!
Mit der letzen Anweisung ( *) ) wird alles abgefangen, was noch übrig ist, quasi eine default-Anwendung.
while-Schleifen
While-Schleifen laufen gewisse Anweisung solange durch, solange die Bedingung erfüllt ist.
Das kann man gebrauchen, wenn man die Zahlen 1-10 ausgeben will, die Schleife muß solange laufen, bis der Zähler nicht kleinergleich als 10 ist (immer dran denken: solange die Bedingung erfüllt ist ).
Auch hier wieder ein Beispiel:
#!/bin/bash
#Programm while.sh
count=0 #Zähler auf Null setzen
#So lange durchlaufen bis count nicht mehr unter 10 ist
while [ $count -le 10 ]
do
echo $count #Zähler ausgeben
count=$[$count+1] #Zähler um eins erhöhen
done
exit 0
|
Und einfach ausführen: Jetzt werden die Zahlen von 0 bis 10 hochgezählt:
[tux]$ ./while.sh
0
1
2
3
4
5
6
7
8
9
10 |
Leider ist die Syntax hier etwas schwieriger:
Zuerst setzen wir unseren Zähler count auf 0: count=0
Jetzt kommt die while-Bedingung: while [ $count -le 10 ] ; das dürfte dir zum Teil schon von der If-Else Anweisung bekannt vorkommen. Also, wir setzen hier als Bedingung count kleinergeich 10 ( $count -le 10 ).
In der do-Anweisung steht drin, was ausgeführt wenn die Bedingung erfüllt ist. Wir geben hier den Wert des Zähler aus ( echo $count ) und erhöhen den Zähler um eins ( count=$[$count+1] ).
for-Schleifen
Die for-Schleife verhält sich unter der bash anders als unter C, und deswegen spreche ich sie nur ganz kurz hier an.
Hier ein Beispielprogramm:
#!/bin/bash
#Programm for.sh
for i in "Hallo du" da "am Moni" t or
do
echo $i
done
exit 0
|
Einfach ausführen und das Ergebnis bitte erst mal selber auswerten:
[tux]$ ./for.sh
Hallo du
da
am Moni
t
or
|
For-Schleifen arbeiten der Reihe nach die angegebene Liste ab. Für Skripte ist das kaum zu gebrauchen aber für Dateioperationen ganz nützlich :
| [tux]$ for i in *.sh; do cp $i $i.bak; done
|
Damit wird von alle Dateien im aktuellen Verzeichnis die auf .sh enden eine Kopie erstellt. Diese Kopie bekommt am Ende ein .bak angehängt.
Dialog
Zum Ende kommen wir zur grafischen Programmierung der bash (naja, es ist bunt und hat Felder). Das kann die bash nicht selber dafür brauchen wir einen kleinen Helfer. Dieser heißt "dialog".
Hier wieder mal ein Beipiel (ist das letzte auf dieser Seite):
#!/bin/bash
#Programm dialog.sh
#Eingabe Fenster mit dialog erzeugen
dialog --clear --inputbox "Sag was" 10 60 2> eingabe.tmp
clear #Bildschirm löschen
#Eingabe einlesen und ausgeben
echo "Du sagtest: `cat eingabe.tmp`"
exit 0
|
Und ausprobieren ... :

Du sagtest: Hallo Tux !
[tux]$
|
Das Wichtigste ist, dass du den eingegeben Text von dialog nicht direkt
nutzen kannst, du mußt ihn in eine Datei schreiben ( 2> eingabe.tmp
).
Dann lesen wir diese Datei aus ( `cat eingabe.tmp`) und geben den Text aus. Hier sind die Anführungszeichen sehr wichtig (es sind die mit
Shift+TasteNebenBackspace ).
So das war ein kleiner Auflug in die bash Programmierung, wenn du selber Skripte schreiben willst, dann tu es :-))
Ein kleiner Tipp: Man kann viel lernen wenn man sich fertige Skripte ansieht, zum Beispiel die Startskripte in /etc/init.d.