Teil 6: Funktionen und Module

Baukastensystem

Programmiersprachen sind dazu gedacht, Computer-Befehle in menschlich lesbarer Form aufzuschreiben. Dazu gehört mehr als nur verständliche Befehle – eine übersichtliche Strukturierung und Untergliederung tut Not.

Einfache Bash-Skripte werden in aller Regel heruntergeschrieben – die Befehle stehen in genau der Reihenfolge untereinander, in der sie später ausgeführt werden. Was bei wenigen Zeilen sinnvoll und leicht lesbar ist, wird bei langen Programmen zum Problem: Wenn das Auswerten der Kommandozeilen-Parameter direkt unter dem Einlesen einer Konfigurationsdatei steht und dann der Aufbau einer Bedienoberfläche folgt, verliert man schnell den Überblick über den Programmablauf. Im Vergleich sind die drei Anweisungen KonfigurationLesen, ParameterAuswertung und Bildmaske viel besser zu verstehen. Die Zusammenfassung von Befehlen zu einer Einheit, die einem bestimmten Zweck dient, nennt man Funktion.

Funktionelle Einheiten

Die Verwendung von Funktionen bietet neben besserer Übersichtlichkeit weitere Vorteile. Die Beispiel-Funktion Bildmaske, sie stellt eine einfache Bedienoberfläche dar, wird mehr als ein mal im Programm gebraucht. Nach jeder Bilschrimausgabe muss die Oberfläche aktualisiert werden – indem die Funktion aufgerufen wird. Soll die Darstellung später einmal verändert werden, brauchen Sie nur die Funktion anzupassen anstatt im Programm herumzusuchen und am Ende gar eine Stelle zu vergessen.

Bash-Funktionen sind fast vollwertige Programme, sie können Parameter übergeben bekommen, haben ihre eigenen Variablen und liefern am Ende einen Exit-Status an den Aufrufer zurück. Das erste Beispiel ParameterListe ist eine Funktion, die alle Parameter ausgibt:

function ParameterListe ()
 {
   echo "$@"
 }

Das einleitende Schlüsselwort function kann entfallen, wichtig sind nur die beiden runden Klammern hinter dem Namen der Funktion. Alle Anweisungen, die zur Funktion gehören, stehen in den geschweiften Klammern. Etwas verwirrend ist anfangs die Handhabung der Spezial-Variablen $1, $2, $3 usw. Bei Programmaufruf enthalten sie die Kommandozeilen-Parameter, analog beim Aufruf einer Funktion die Funktions-Parameter. Das bedeutet jedoch, dass Sie innerhalb einer Funktion nicht an die Kommandozeilen-Parameter herankommen – wenn nötig müssen Sie sie beim Aufruf mitgeben.

Der Aufruf einer Funktion erfolgt analog zu dem jedes anderen Programms – hinter dem Namen werden die Parameter als mit Leerzeichen, Tabulator oder Enter getrennte Liste übergeben:

ParameterListe $1 $2
   ParameterListe Hallo Welt

Ist die Funktion abgearbeitet, wird das Programm mit der dem Aufruf folgenden Anweisung fortgesetzt, meist ist das die nächste Zeile. Funktionen haben grundsätzlich einen Rückgabewert. Er entspricht dem Ergebnis des letzten Befehls, der in der Funktion abgearbeitet worden ist, er kann aber auch mittels return explizit gesetzt werden.

Geltungsbereich von Variablen

Für die in Funktionen verwendeten Variablen gibt es einige Besonderheiten zu beachten. Ohne Funktionen und Blöcke gelten alle Variablen global im gesamten Programm, $i bezeichnet überall die gleiche Variable. Solche globale Variablengelten ebenfalls innerhalb von Funktionen. Folgendes Beispiel-Programm soll das dadurch entstehende Problem veranschaulichen:

001  #!/bin/bash
 002  Trennzeile ()
 003  {
 004    i=0
 005    while [ $i -lt 10 ]; do
 006      echo -n "*"
 007      i=$[$i+1]
 008    done
 009    echo
 010  }
 011
 012  i=1
 013  while [ $i -lt 4 ]; do
 014    Trennzeile
 015    echo $i
 016    i=$[$i+1]
 017  done

Die Funktion Trennzeile benutzt die Variable $i in der While-Schleife, um eine Zeile mit zehn Sternen auszugeben. Die zweite While-Schleife des Listings im Hauptprogramm soll Trennzeile drei mal aufrufen und dabei jeweils den Wert $i ausgeben. Das Ergebnis sollte so aussehen:

     
 1
      
 2
      
 3

Stattdessen erhalten wir aber nur zwei Zeilen:

     
 10

Der Teufel steckt im Detail: Bei Aufruf des Programms wird die Funktion Trennzeile zunächst nur gelesen, aber nicht ausgeführt. Als erstes wird $i in Zeile 12 auf eins gesetzt, danach die While-Schleife von Zeile 13 bis 17 abgewickelt. Bei Aufruf von Trennzeile in Zeile 14 ist $i noch eins, doch die Variable wird in Zeile 7 verändert. Am Ende der Funktion (Zeile 9) ist $i schließlich zehn. Das Programm wird nach Abarbeitung der Funktion in Zeile 15 fortgesetzt, gibt auf dem Bildschirm 10 aus und erhöht $i um eins. Vor erneuter Ausführung der Schleife wird die Bedingung aus Zeile 13 überprüft, und stellt sich als falsch heraus – die While-Schleife wird verlassen und das Programm endet.

Die Ursache ist die Verwendung der globalen Variablen $i innerhalb unserer Funktion, damit greifen wir ungewollt in das Hauptprogramm ein. Doch wie kann man sicher gehen, nicht mit den Variablen-Namen des Hauptprogramms oder anderer Funktionen ins Gehege zu kommen?

LinuxCommunity kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ähnliche Artikel

  • Bash-Kurs Teil 6
    Die elementaren Konfigurationsmöglichkeiten mit eingebauten Funktionen der Bash sind der Schwerpunkt dieses Teils. Im nächsten wird ein komfortables Tool zur Erzeugung von Konfigurationsdateien vorgestellt.
  • Teil 2: Grundlagen der Bash
    Nachdem wir uns in der letzten Ausgabe die Metazeichen sowie die grundlegende Verwendung von Variablen angesehen haben, stoßen wir heute in das Reich der mehrdimensionalen Variablen vor und beschäftigen uns am Ende noch mit der Verarbeitung von Zeichenketten.
  • Doppeltes Lottchen
    Batsh schlägt zwei Fliegen mit einer Klappe: In dieser Sprache geschriebene Programme lassen sich sowohl in Bash-Skripte als auch in die unter Windows genutzten Batch-Dateien übersetzen.
  • Teil 3: String-Verarbeitung und Reguläre Ausdrücke
    Die Grundlagen der Zeichenketten haben wir in der letzten Ausgabe gelegt. Diesmal wollen wir uns aber nicht mit einfachen Leer-Tests oder Längenanzeigen begnügen, sondern unsere Strings kräftig durcheinander wirbeln.
  • Teil 1: Grundlagen der BASH
    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.
Kommentare

Infos zur Publikation

LU 06/2017: System im Griff

Digitale Ausgabe: Preis € 5,95
(inkl. 19% MwSt.)

LinuxUser erscheint monatlich und kostet 5,95 Euro (mit DVD 8,50 Euro). Weitere Infos zum Heft finden Sie auf der Homepage.

Das Jahresabo kostet ab 86,70 Euro. Details dazu finden Sie im Computec-Shop. Im Probeabo erhalten Sie zudem drei Ausgaben zum reduzierten Preis.

Bei Google Play finden Sie digitale Ausgaben für Tablet & Smartphone.

HINWEIS ZU PAYPAL: Die Zahlung ist ohne eigenes Paypal-Konto ganz einfach per Kreditkarte oder Lastschrift möglich!

Aktuelle Fragen

Knoppix-Live-CD (8.0 LU-Edition) im Uefiboot?
Thomas Weiss, 26.04.2017 20:38, 2 Antworten
Hallo, Da mein Rechner unter Windows 8.1/64Bit ein Soundproblem hat und ich abklären wollte, o...
Grub2 reparieren
Brain Stuff, 26.04.2017 02:04, 5 Antworten
Ein Windows Update hat mir Grub zerschossen ... der Computer startet nicht mehr mit Grub, sondern...
Linux open suse 2,8
Wolfgang Gerhard Zeidler, 18.04.2017 09:17, 2 Antworten
Hallo.bitte um Hilfe bei. Code fuer den Rescue-login open suse2.8 Mfg Yvo
grep und sed , gleicher Regulärer Ausdruck , sed mit falschem Ergebnis.
Josef Federl, 15.04.2017 00:23, 1 Antworten
Daten: dlfkjgkldgjldfgl55.55klsdjfl jfjfjfj8.22fdgddfg {"id":"1","name":"Phase L1","unit":"A",...
IP Cams aufzeichnen?
Bibliothek der Technischen Hochschule Mittelhessen / Giessen, 07.04.2017 09:25, 7 Antworten
Hallo, da nun des öfteren bei uns in der Nachbarschaft eingebrochen wird, würde ich gern mein...