Hallo Welt!

Teil 1: Grundlagen der BASH

01.12.2000
Haben Sie auch schon einmal am Computer gesessen und sich über immer wiederkehrende Arbeit geärgert, die man mit einem kleinen Programm vereinfachen könnte? Im ersten Teil unseres Programming Corners steigen wir in die Welt der Programmierung ein.

Warum sollte man überhaupt anfangen, selbst Programme zu schreiben? Gibt es nicht schon genug Programmierer auf der Welt? Das Problem ist, viele Dinge funktionieren zwar schon im Ansatz, sind aber einfach für den eigenen Gebrauch zu komliziert oder unkomfortabel. Da wünscht man sich schnell seinen privaten Programmierer, der hier und da etwas feilt und zum Schluss eine optimale Bedienbarkeit hinbekommt. Was liegt näher, als sein eigener Privat-Programmierer zu sein? Der Programming Corner soll einen Einstieg in die Welt der Programmierung bieten, und zwar mit einfachsten Mitteln.

Programmiersprache BASH

Die Bourne-Again SHell, kurz BASH, hat sich als Standard-Shell der meisten Linux-Distributionen etabliert. Doch sie ist mehr als eine einfache Kommandozeile zum Aufruf von Programmen, sie ist vielmehr eine fast komplette Programmiersprache.

Diese Serie wird sich nicht allein mit den Interna der BASH beschäftigen, sondern vielmehr auch das eine oder ander nützliche Programm am Rande streifen. Die Beispiele selbst sind zwar direkt auf die BASH gemünzt, die Programmiertechniken sind weitestgehend universell gehalten und können auch im Zusammenhang mit anderen Sprachen verwendet werden.

Erste Schritte

BASH-Programme werden auch "Scripte" (Protokolle) genannt. Sie beginnen einleitend mit der zu verwendenden Shell und enthalten ansonsten nur Befehle, die Sie auch außerhalb des Programms von Hand eingeben könnten. Hier das (bei Lehrern) allseits beliebte "Hallo Welt!":

#!/bin/bash
echo Hallo Welt!
echo Hallo   Welt!

Die erste Zeile ist strenggenommen eine Kommentarzeile, da sie mit einer Raute # beginnt. Generell gilt, hinter der Raute bis zum Zeilenende stehen nur Kommentare. Auch dürfen Leerzeilen zur besseren Übersicht benutzt werden. In der ersten Zeile befindet sich die Angabe, mit welchem Programm dieses Script verarbeitet werden soll. Das kann neben der BASH auch durchaus Perl oder TCL/TK sein. Per echo wird dann in der zweiten und dritten Zeile Hallo Welt! ausgegeben, gefolgt von einem Zeilenumbruch.

Meta-Character und Escapes

Trotz unterschiedlicher Schreibweise ist das Ergebnis der Zeilen zwei und drei identisch. Der Grund dafür sind Steuerzeichen (sogenannte Meta-Character und Control-Character), die BASH besonders interpretiert. Leerzeichen gelten als Trennung zwischen Parametern eines Befehls, wobei mehrere Leerzeichen hintereinander wie ein einziges wirken. Im Beispiel wird dem Befehl echo mit den Parametern "Hallo" und "Welt" aufgerufen. Von diesen Spezialzeichen gibt es einige, die wichtigsten sind in Tabelle 1 aufgelistet. echo gibt alle Parameter, die keine Steuer-Parameter sind, mit einem Leerzeichen getrennt hintereinander aus. Um mehr als ein Leerzeichen zwischen "Hallo" und "Welt" zu erhalten, müssen wir die Leerzeichen im Zwischenraum escapen – also der BASH mitteilen, dass dies ein echtes Leerzeichen und kein Trenner zwischen Parametern ist. Die Aufgabe es Escape-Zeichens nimmt der Backslash "\" wahr.

echo Hallo\ \ \ Welt!

Soll ein Backslash ausgegeben werden, so muss man ihn selbst escapen, also \\ schreiben. Alternativ können Sie einfache oder doppelte Anführungszeichen (sogenannte Quotes) benutzen, um Leerzeichen und die meisten anderen besonderen Zeichen ihrer Sonderstellung zu entheben:

echo "Hallo Welt!"

Die Quotes nimmt man aber am besten in kleinen Dosen ein, sie werden uns im Laufe dieser Serie immer mal wieder in einem anderen Zusammenhang begegnen und dann quasi "beiläufig" erklärt.

Variablen

Natürlich wäre es langweilig, immer nur feste Texte auszugeben. Um Werte oder Worte zwischenzuspeichern, kennt die BASH Variablen. Anders als in vielen Hochsprachen unterscheidet BASH nicht zwischen verschiedenen Typen, in jeder Variablen können ganzen Zahlen (Dezimalzahlen sind grundsätzlich nicht erlaubt), Buchstaben, Worte oder ganze Sätze gespeichert werden. Eine Variable wird über ihren Namen angesprochen. Sie braucht dabei vor ihrer ersten Verwendung nicht deklariert ("angemeldet") werden, sie entsteht automatisch durch die erste Wertezuweisung. Groß-/Kleinschreibung sind bei den Namen übrigens relevant.

#!/bin/bash
Variable=2
Variable=a
Variable=Hallo
Variable=Hallo\ Welt!
Variable="Hallo Welt!"

Um an den Wert einer Variablen heranzukommen, verwendet man ebenfalls wieder ihren Namen, mit vorangestelltem Dollar-Zeichen "$". Alternativ können Sie den Namen zusätzlich in geschweifte Klammern einfassen – diese Variante wird gebraucht, wenn dem Variablen-Namen unmittelbar ein Buchstabe folgt:

Wert=100
echo $Wert DM
echo ${Wert}DM

Die zweite Zeile liefert "100 DM", während die dritte "100DM" ohne Leerzeichen zwischen Betrag und Währungseinheit ausgibt. Ohne geschweifte Klammern hätten wir den Inhalt der (nicht existenten) Variablen $WertDM bekommen. Nicht existente Variablen haben stets keinen Wert, sie sind einfach leer.

BASH ersetzt die Variablen-Namen übrigens an fast jeder Stelle durch die Werte der Variablen, man spricht hier von der Auflösung der Variablen. Die einzige Ausnahme sind die Hochkomma "'" – was dort zwischen steht, wird nicht ersetzt. Um den Namen der Variablen inklusive Dollar-Zeichen zu bekommen, können wir alternativ auch das "$" escapen:

Wert=100
Wert="$Wert DM"
echo Inhalt der Variablen '$Wert': $Wert
echo Inhalt der Variablen \$Wert: $Wert

In der zweiten Zeile haben wir Wert eine Zeichenfolge zugewiesen, in der die Variable selbst vorkommt. Die BASH wertet dabei zunächst den Teil rechts vom Gleichheitszeichen aus, wobei für $Wert die Ziffern 100 eingesetzt werden – auf der rechten Seite steht dann "100 DM". Erst danach wird das Ergebnis der rechten Seite (der sogenannte R-Value) der Variablen auf der linken Seite des Gleichheitszeichens (dem sogenannten L-Value) zugewiesen. Diese Behauptung kann man übrigens mit einem kleinen Programmbeispiel beweisen, dazu mehr in der nächsten Folge.

Arithmetische Operationen und Null-Funktion

Mit Zuweisungen allein ist noch nicht viel Staat zu machen, oft braucht man Zähler oder möchte kleine Berechnungen anstellen. Die BASH bietet dazu einige Operatoren, darunter die Grundrechenarten, logische Operatoren und Binäroperationen. Bis auf die logischen Operatoren wie Vergleiche müssen Sie aber sicher stellen, dass Sie wirklich nur mit Zahlen arbeiten. Der Pferdefuß ist, dass BASH in einer Variablen sowohl Text als auch Zahlen speichern kann, und nur Sie dafür verantwortlich sind, dass Sie nicht mit Buchstaben rechnen. Schauen Sie sich noch einmal die ersten zwei Zeilen des letzten Beispiels an. In der ersten Zeile war in Wert noch eine Zahl, in der zweiten Zeile dann haben wir "DM" angehängt und so aus der Zahl plötzlich eine Zeichenkette (auch String genannt) gemacht. Wir dürfen nun mit Wert nicht mehr rechnen. Tun Sie es trotzdem, bricht BASH Ihr Programm mit Fehlermeldung ab.

Es gibt zwei Schreibweisen für Berechnungen, die Anweisung wird entweder in eckige Klammern oder in doppelte runde Klammern eingeschlossen. Zudem wird ein Dollar vorangestellt. Beide Schreibweisen sind im nächsten Beispiel zu sehen:

Wert=$[$Wert+1]
Wert=$(($Wert+1))
: $[Wert+=1]
: $((Wert+=1))

Insgesamt machen alle vier Zeilen genau das gleiche, sie erhöhen den Inhalt von Wert um eins. Zeile eins und zwei sind noch recht leicht zu durchschauen, hier wird wie üblich zunächst der R-Value ausgewertet und dann dem L-Value zugewiesen. Zeile drei und vier arbeiten vom Prinzip her gleich, denn die Operation "a+=b" ist definiert als "a=$a+b" – intern wandelt BASH die Kurzschreibweise. Ungewöhnlich ist hier der Doppelpunkt vor der Rechenanweisung. Er ist eine Null-Funktion, ein Befehl, der nichts tut. Der für uns wichtige Nebeneffekt: Die BASH wertet die Parameter dahinter genauso wie beim Aufruf jeden anderen Befehls aus, berechnet somit das Ergebnis. Notwendig ist der Doppelpunkt, weil die Rechenoperationen stets durch das Ergebnis, nämlich $Wert, ersetzt werden – ohne den Doppelpunkt wäre dies für BASH ein Befehl, der aufgerufen würde.

Neben den Grundrechenarten verfügt die BASH diverse logische und Binäroperatoren, die aber nur selten verwendet werden. Für die meisten Operatoren gibt es zusätzlich Zuweisungs-Operatoren wie in unserem Beispiel +=, die das Lesen von Programmen durchaus einfacher machen können. Eine Übersicht der Operatoren finden Sie in Tabelle 2.

Damit endet die erste Folge, nächstes mal wird es im Programming Corner um die Verarbeitung von Zeichenketten gehen, außerdem werden wir Ihnen Arrays vorstellen und die Verwendung an Beispielen erklären. (mdö)

Tabelle 1: Steuer- und Sonderzeichen der BASH

Zeichen Funktion
Leerzeichen (space) Trenner zwischen Programm-Parametern
Tabulator (tab) Trenner zwischen Programm-Parametern
Return (newline) Befehlseingabe
\ (backslash) Escape-Zeichen
| (pipe) Verkettung der Ein-/Ausgabe mehrerer Programme
& (ampersand) Programm als Hintergrund-Prozess starten, Ein-/Ausgabeumleitung
; (semikolon) Trenner zwischen zwei Programmaufrufen
(, ) (braces) Gruppierung, Berechnung
< (input redirect) Eingabe-Umleitung
> (output redirect) Ausgabe-Umleitung
|| (logical or) Verknüpfung zweier Befehle mit "ODER"
&& (logical and) Verknüpfung zweier Befehle mit "UND"
;; Ende eines case-Falls

Tabelle 2: BASH-Operatoren

Operator/Zuweisungs-Operator Funktion
+, -, *, / +=, -=, *=, /= Grundrechenarten
% %= Rest der ganzzahligen Division (5%2=1)
! Logische Negation (!1 = 0, !0 = 1)
&& Logisch UND (a und b)
|| Logisch ODER (a oder b)
==, != Gleichheit, Ungleichheit
<=, >=, <, > Vergleich größer/kleiner
~ Binäre Invertierung (~1101 = 0010)
& &= Binär UND (1011 & 1101 = 1001)
| |= Binär ODER (1100 | 0101 = 1101)

Versionenkonflikt

Die hier im Artikel gezeigten Beispiele beziehen sich allesamt auf die Version 2 der BASH und sind mit der alten Version 1 nur zum Teil oder auch gar nicht anwendbar. Obwohl die Version 2 nun seit über zwei Jahren in Gebrauch ist und sich bislang keine nennenswerten Probleme gezeigt haben, installieren manche Distributionen-Hersteller wie Red Hat oder Caldera nach wie vor die alte Version 1.4 unter /bin/bash, liefern die Version 2 aber als /bin/bash2 mit.

Deshalb müssen Sie sich gleich als erstes vergewissern, welche Version bei Ihnen über /bin/bash angesprochen wird:

/bin/bash -c 'echo $BASH_VERSION'

Ist /bin/bash die Version 1, müssen Sie sich auf die Suche nach Version 2 machen – sie wird vermutlich in bin liegen und bash2 heißen:

ls /bin/bash2

Meldet ls, er könne /bin/bash2 nicht finden, sollten Sie auf den Installations-CDs Ihrer Distribution nachsehen und das Paket wenn nötig nachinstallieren. In den Programmbeispielen im Artikel müssen Sie dann stets anstelle /bin/bash /bin/bash2 einsetzen, damit die Programme mit der Version 2 arbeiten.

Alternativ können Sie Ihr System auch komplett auf BASH 2 umstellen. Das bedeutet, die Datei /bin/bash muss in /bin/bash1 umkopiert werden und anschließend müssen Sie /bin/bash2 nach /bin/bash kopieren. Eigentlich reicht auch Umbenennen, doch dann würden Programme, die /bin/bash2 verwenden, nicht mehr funktionieren, weshalb /bin/bash2 erhalten bleiben sollte. Das eigentliche Problem ist: Sie können nicht einfach eine Datei überschreiben oder bewegen, die in Benutzung ist – und da Sie als root normal /bin/bash benutzen, müssen wir zunächst mit einem Trick /bin/bash frei machen.

Dazu loggen Sie sich zunächst als root ein und stellen nochmals sicher, dass es wirklich /bin/bash2 gibt. Ist dem nicht so, dürfen Sie die folgenden Schritte auf gar keinen Fall durchführen, oder Sie riskieren, sich nie wieder als root einloggen zu können! Um im Fehlerfall noch einen Notnagel zu haben, sollten Sie zusätzlich auf eine Text-Konsole wechseln und sich dort als root einloggen. diese Konsole werde ich der Einfachheit halber jetzt als "Notkonsole" bezeichnen. Auf dieser Notkonsole geben Sie zunächst nichts weiter ein, sondern wechseln wieder auf Ihre Arbeitskonsole. Dort ändern Sie die Voreinstellung der Shell für den Benuzter root:

chsh -s /bin/bash2 root

Loggen Sie sich jetzt nicht aus, sondern schalten Sie auf eine freie Textkonsole und loggen Sie sich dort wieder als root ein. Hat alles geklappt, liefert Ihnen echo $BASH_VERSION auf dieser Konsole die Version 2. Können Sie sich nicht einloggen, ist irgend etwas schief gegangen und Sie müssen unbedingt den alten Zustand wieder herstellen. Dazu wechseln Sie auf die Notkonsole und ändern mit chsh -s /bin/bash root die Login-Shell wieder auf den Anfangswert.

Hat das Login geklappt, haben Sie nun eine neue Notkonsole, und loggen sich aus der alten und aus allen anderen Konsolen aus. Es kann auch notwendig werden, KDE oder GNOME zu schließen. Als einziges bleibt nun die neue Notkonsole übrig. Nun folgt die Umstellung von BASH 1 auf BASH 2.

Dazu loggen Sie sich auf einer neuen Konsole wiederum als root ein und kopieren nun bash zu bash1 und anschließend bash2 zu bash:

cp /bin/bash /bin/bash1
cp /bin/bash2 /bin/bash

Als letzte Aktion setzen Sie die Login-Shell von root wieder zurück:

chsh -l /bin/bash root

Können Sie sich auf einer weiteren Konsole wieder als root einloggen und bekommen Version 2 der BASH angezeigt, hat der Umbau geklappt. Nun ist die Version 2 Ihre Standard-Shell und Sie können wieder ganz normal weiterarbeiten.

Befehle

echo Gibt alle Parameter durch je ein Leerzeichen voneinander getrennt aus.
(Doppelpunkt) Null-Funktion, hat keine direkte Wirkung. Wird teilweise für arithmetische Operationen oder Variablen-Manipulationen benutzt. Die eigentlichen Operationen werden als Parameter der ":"-Funktion angegeben.
$[..] Berechnet den in der Klammer stehenden arithmetischen Ausdruck und liefert das Ergebnis.
$((..)) Berechnet den in der Klammer stehenden arithmetischen Ausdruck und liefert das Ergebnis.

Glossar

Meta-Character

Sonderzeichen, wird in besonderer Weise interpretiert.

Control-Character

Veranlasst eine Aktion oder Sonderbehandlung der Befehlszeile.

Escape-Zeichen

Hebt die Wirkung von Meta-, Control- und Escape-Charactern auf.

Quotes

Anführungszeichen, Hochkommas und umgedrehte Hochkommas. Sie sorgen dafür, dass ein Großteil der Meta- und Control-Character nicht mehr als solche interpretiert werden. Sie müssen stets paarweise verwendet werden.

R-Value

Das Ergebnis der Anweisung rechts vom Gleichheitszeichen

L-Value

Die Variable links des Gleichheitszeichens, in der der R-Value gespeichert wird

Script

engl. "Protokoll", man bezeichnet damit allgemein Shell- und manchmal auch Perl-Programme. Das Script ist stets eine Text-Datei, die man sich direkt anzeigen lassen kann.

LinuxCommunity kaufen

Einzelne Ausgabe
 
Abonnements
 

Ähnliche Artikel

Kommentare