Home / LinuxUser / 2001 / 07 / Teil 6: Funktionen und Module

Newsletter abonnieren

Lies uns auf...

Folge LinuxCommunity auf Twitter

Top-Beiträge

Mandriva gibt Distribution in die Hände der Community
(271 Punkte bei 22 Stimmen)

Heftarchiv

LinuxUser Heftarchiv

EasyLinux Heftarchiv

Ubuntu User Heftarchiv

Ubuntu User Heftarchiv

Partner-Links:

Shopping
Topsuche
 
Yatego Deutschlands größte Shoppingmall. 10000 Shops,
3.5 Mio Artikel. Alle Bestseller, Servertechnik und Technik Themenwelten.

Notebooks und Netzwerkhardware bei Mercateo günstig kaufen.
Internet Telefonie mit VoIP Telefonen von Gigaset
Das B2B Portal www.Linx.de informiert über Produkte und Dienstleistungen.
Günstige Digitalkameras finden Sie im Preisvergleich.

Baukastensystem

Teil 6: Funktionen und Module

01.07.2001 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?

Einem Freund empfehlen    Druckansicht Bookmark and Share
Kommentare

1146 Hits
Wertung: 0 Punkte (0 Stimmen)

Schlecht Gut

Infos zum Autor

Mirko Dölle

Redakteur für Linux bei c't, Heise Zeitschriften Verlag; ehemals Competence Center Hardware/Linux-Magazin, Linux New Media AG


Infos zur Publikation

Infos zur Publikation

LinuxUser 06/2012

Aktuelle Ausgabe kaufen:

Heft bestellen Heft als PDF kaufen

LinuxUser erscheint monatlich und kostet in der Nomedia-Ausgabe EUR 5,50 und mit DVD EUR 8,50. Weitere Informationen zum Heft finden Sie auf der LinuxUser-Homepage.

Im LinuxUser-Probeabo erhalten Sie drei Ausgaben für 3 Euro. Das Jahresabo (ab EUR 56,10) können Sie im LNM-Shop bestellen.

Tipp der Woche

Adobe AIR
Adobe-AIR-Programme installieren und (manuell) starten
Tim Schürmann, 14.05.2012 13:09, 0 Kommentare

Es gibt sie noch: neue Anwendungen, die Adobes Integrated Runtime voraussetzen. Aktuellstes und vermutlich auch größtes Beispiel ist das Adventure Botanicula

Aktuelle Fragen

gibt es ein Kommandozeilen Tool, um ein X11-Fenster in ein Anderes einzubetten?
GoaSkin , 21.05.2012 16:44, 0 Antworten
Das XEmbed-Protokoll ist u.A. dazu gedacht, dass man eine X11-Anwendung in eine andere wie ein Wi...
Apache2, Options -Indexes geht nicht
no no, 12.05.2012 19:01, 8 Antworten
Habe in apache2.conf folgendes stehen: Options -Indexes ...
LInux auf Dell LS H500
Andreas Endresl, 09.05.2012 08:54, 2 Antworten
Habe einen alten Dell Latitude LS H500 nur mit ext. Floppy und CD es geht nur immer eines von den...
Datenwiederherstellung unter Ubuntu 12.04 mit "Simple Backup" nach Umzug von Linux Mint
Christian Lottmann, 07.05.2012 13:33, 0 Antworten
Vor dem Umzug auf Ubuntu 12.04 habe ich unter Linux MInt mit "Simple Backup" voll (15.4.2012) und...
DKMS für den propritären NVIDIA-Treiber
Commander Data, 26.04.2012 22:02, 2 Antworten
Hallo an die Gemeinde. Ich habe hier ein interessantes Stück openSuSE gefunden. http://forums.op...