Script-Programmierung

Variablen und Arrays in der bash

  1. Variablen

  2. Arrays


Die bash unterstützt die Verwendung von Variablen und eindimensionalen Arrays. Diese müssen vor der ersten Benutzung im Gegensatz zu anderen Programmiersprachen nicht vorher deklariert werden. Das vereinfacht zum einen den Code und erleichtert zunächst auch die Programmierung, bringt aber auch Probleme mit sich, da sich durch schlampige Programmierung sehr leicht Fehler einschleichen können. Die Kommandos declare und typeset schaffen hier nur begrenzt Abhilfe. Allgemein werden Variablen durch eine Wertzuweisung deklariert, indem sie erstmals mit ihrem Namen aufgerufen werden.

  1. Variablen

    Die Verwendung von Variablen in einem Script könnte folgendermaßen aussehen:
    #!/bin/bash
    TESTA=
    TESTB=1
    TESTC=/var/log/
    TESTD=Hallo
    TESTE="Hallo Oma"
    TESTF=$TESTC
    TESTG="$TESTC ist ein Pfad in der Variable \$TESTC"
    TESTH=$((TESTB+8))
    TESTI=$(date)
    TESTJ='$TESTC'
    echo "Die Variable TESTA enthält den Wert $TESTA"
    echo "Die Variable TESTB enthält den Wert $TESTB"
    echo "Die Variable TESTC enthält den Wert $TESTC"
    echo "Die Variable TESTD enthält den Wert $TESTD"
    echo "Die Variable TESTE enthält den Wert $TESTE"
    echo "Die Variable TESTF enthält den Wert $TESTF"
    echo "Die Variable TESTG enthält den Wert $TESTG"
    echo "Die Variable TESTH enthält den Wert $TESTH"
    echo "Die Variable TESTI enthält den Wert $TESTI"
    echo "Die Variable TESTJ enthält den Wert $TESTJ"
    Die Zeilen des Scripts im einzelnen haben folgende Bedeutung.
    Die Variable TESTA wird deklariert, aber es wird kein Wert zugewiesen. Die Variable enthält einen Nullstring, also eine Zeichenkette ohne Zeichen.
    Die Variable TESTB wird deklariert und es wird der Wert 1 zugewiesen. Da kein Variablentyp festgelegt wurde, entscheidet der Kontext in dem die Variable verwendet wird, ob es sich um einen String oder eine Integerzahl handelt.
    In der Variable TESTC wird der Name eines Pfades abgelegt und in TESTD das Wort Hallo.
    In die Variable TESTE soll nun ein Text mit Leerzeichen abgelegt werden. Hier ist eine Quotung des Leerzeichens undbedingt notwendig. Der Text wurde dazu in Anführungszeichen gesetzt und das Leerzeichen so vor der bash versteckt. Die Variable enthält danach nur den Text innerhalb der Anführungszeichen, da diese als Quotungszeichen vor der Wertzuweisung entfernt werden. Die bash interpretiert also auch diese Zuweisungszeilen, ähnlich, wie sie es bei Kommandoaufrufen auch tut. Siehe dazu die Erklärungen zum Quoting im Abschnitt Hallo Welt.
    Die Zuweisung der Variable TESTF ist nun eine Besonderheit. Das Zeichen $ ist ein Sonderzeichen der bash und bewirkt eine Parameterexpansion. Dabei ersetzt die bash den Code $TESTC durch den Inhalt der Variablen TESTC und dieser wird dann der Variablen TESTF zugewiesen. Die Variablen TESTF und TESTC haben damit den selben Inhalt.
    Da die Expansionen der bash ein sehr mächtiges Werkzeug ist, kann man auch die Wertzuweisungen sehr flexibel gestalten. So wird der Variable TESTG ein Text zugewiesen, der den Inhalt der Variable TESTC enthält. Das Sonderzeichen $ wird durch die doppelten Anführungszeichen nicht gequotet, sondern nur durch einfache Anführungszeichen oder den backslash.
    Bevor die Variable TESTH zugewiesen wird, führt die bash eine Arithmeticexpansion durch, dazu wird der Inhalt der Variable TESTB mit 8 addiert und das Ergebnis in TESTH gespeichert. Die bash erlaubt in der Arithmeticexpansion eine ganze Reihe von Integeroperationen. Sollte die Variable TESTB keine Zahl, sondern Text enthalten, so wird dieser als Null interpretiert.
    Bei der Zuweisung der Variable TESTI kommt nun eine weitere Expansion zum Einsatzt und zwar die Kommandosubstitution. Dabei wird durch die bash das Kommando date Kommando ausgeführt und die Ausgabe des Kommandos auf Standardout in die Variable umgeleitet. Da das Kommando date das Systemdatum ausgibt, ist dieses nun in der Variable abgelegt.
    Die hier beschriebenen Expansionen sind keine Besonderheit der Variablenzuweisung, sondern eine grundlegende Funktionalität der bash. Sie kann überall in Scripten zur Anwendung kommen.
    In den folgenden Zeilen werden die Inhalte der Variablen durch das echo-Kommando wieder ausgegeben.
  2. Arrays

    Die Arbeit mit Arrays funktioniert auf ähnliche Weise, wie die Arbeit mit Variablen. In der bash sind Arrays grundsätzlich eindimensional und werden mit einem nicht negativen Integerwert indiziert. Das erste Arrayfeld wird also mit 0 (Null) und die weiteren mit 1, 2, 3... adressiert. Arrays dürfen auch "Löcher" besitzen, d.h. der Index muss nicht fortlaufend benutzt werden. Im Normalfall ist der Inhalt der einzelnen Arrayelemente typfrei, mit declare und typeset kann jedoch der Typ der Arrayelemente festgelegt werden. Besonderheiten entstehen durch die Verwendung der Sonderzeichen @, * und #. Die Zeichen @ und * stellen einen Bezug zu allen Elementen des Arrays her. Sie verhalten sich ähnlich wie bei der Verwendung der Positionsparameter der bash in der Parameterübergabe. Dadurch kann sich z.B. die Bestimmung der Länge durch # einmal auf ein einzelnes Arrayelement und einmal auf das ganze Array beziehen. Die Zuweisung des Arrayinhaltes geschieht entweder durch Zuweisung der einzelnen Arrayelemente oder durch Zuweisung des gesamten Arrays. Hier wieder ein Beispielscript:
    #!/bin/bash
    FELDA[0]=
    FELDA[1]=1
    FELDA[2]=/var/log/
    FELDA[10]=Hallo
    FELDA[17]="Hallo Oma"
    FELDA[18]=${FELDA[2]}
    FELDB=(3 4 "der test" /var/spool )
    FELDC=([1]=7 23 [10]="wert" [20]=19 21 33 "$(date)" )
    echo "Das Arrayelement FELDA[0] enthält den Wert ${FELDA[0]}"
    echo "Das Arrayelement FELDA[2] enthält den Wert ${FELDA[2]}"
    echo "Das Arrayelement FELDA[3] enthält den Wert ${FELDA[3]}"
    echo "Das Array FELDA enthält die Elemente ${FELDA[*]}"
    echo "Das Array FELDB enthält die Elemente ${FELDB[*]}"
    echo "Das Arrayelement FELDC[0] enthält den Wert ${FELDC[0]}"
    echo "Das Arrayelement FELDC[1] enthält den Wert ${FELDC[1]}"
    echo "Das Arrayelement FELDC[2] enthält den Wert ${FELDC[2]}"
    echo "Das Arrayelement FELDC[3] enthält den Wert ${FELDC[3]}"
    echo "Das Arrayelement FELDC[10] enthält den Wert ${FELDC[10]}"
    echo "Das Arrayelement FELDC[10] enthält ${#FELDC[10]} Zeichen"
    echo "Das Array FELDC[10] enthält ${#FELDC[*]} Elemente"
    Die Zeilen bedeuten im Einzelnen:
    Es werden drei Arrays FELDA, FELDB und FELDC deklariert.
    Das Arrayelement FELDA[0] wird mit einem Leerstring belegt, das Array ist damit definiert.
    In den beiden folgenden Feldern werden die Werte 1 und /var/log/ abgelegt. Dann wird das Array weiter mit Lücken definiert, d.h. es gibt freie Arrayelemente, die bei der Abfrage einen Leerstring enthalten. Die Arrayelemente 10 und 17 enthalten zwei Strings. Dem Arrayelement 18 wird der Wert aus dem Arrayelement 2 zugeordnet, beide enthalten damit den String /ver/log/.
    Das Array FELDB wird komplett und fortlaufend definiert, es werden die Arrayelemente 0 bis 3 werden mit Werten belegt. Wird ein Array auf diese Weise definiert, dann gehen alle vorher im Array gespeicherten Werte verloren. Mit dieser Methode können freie Arrayelemente also nicht nachgeladen werden.
    Das Array FELDC wird auch komplett und mit Lücken definiert, indem mit dem Index [indexnummer]= die genaue Postition der Feldelemente festgelegt wird. Dieses Array enthält damit seine Werte in den Arrayelementen 1, 2, 10, 20, 21, 22 und 23.
    Die folgenden Zeilen dienen der Ausgabe verschiedener Arrayelemente. Zur Abfrage der Arrayinhalte ist die Verwendung der geschweiften Klammer (brace) zwingend notwendig. Außerdem ist es möglich, die Länge einzelner Inhalte, sowie die Anzahl der Feldelemente im Array abzufragen.





  3. Sollte jemand seine Rechte durch eine Veröffentlichung auf dieser oder einer anderen meiner Seiten verletzt sehen, bitte ich um sofortige Kontaktaufnahme. Ich werde die entsprechenden Inhalte umgehend entfernen. Somit sind sowohl ein anwaltlicher Rat als auch eine kostenpflichtige Abmahnung nicht erforderlich! Weiterhin weise ich darauf hin, dass der Inhalt verlinkter Seiten nicht in meiner redaktionellen Verantwortung liegt.
    Vielen Dank

    www.schlaefendorf.de 2012

    www.linux-web.de