Kapitel 2 Variablen
Keine Programmiersprache kommt ohne Variablen aus. Variablen werden gewöhnlich dazu verwendet, Daten (Zahlen oder Zeichenketten) zu speichern, um zu einem späteren Zeitpunkt wieder darauf zurückzugreifen. Allerdings finden Sie bei der Shellscript-Programmierung im Vergleich zu vielen anderen Programmiersprachen zunächst keine speziellen Datentypen, bspw. für Zeichenketten, Fließkomma- oder Integerzahlen.
2.1 Grundlagen
 
Eine Variable besteht aus zwei Teilen: dem Namen der Variable und dem entsprechenden Wert, den diese Variable repräsentiert bzw. speichert. Hier die Syntax:
variable=wert
Der Variablenname kann aus Groß- und Kleinbuchstaben, Zahlen und Unterstrichen bestehen, darf allerdings niemals mit einer Zahl beginnen. Die Maximallänge eines Variablennamens beträgt 256 Zeichen, wobei er auf vielen Systemen auch etwas länger sein darf (ob ein solch langer Name sinnvoll ist, sei dahingestellt). Wichtig ist es auch, die Lebensdauer einer Variablen zu kennen, welche nur so lange wie die Laufzeit des Scripts (genauer der ausführenden Shell) währt. Beendet sich das Script, wird auch die Variable ungültig (sofern diese nicht exportiert wurde – dazu mehr in Abschnitt 2.6). Der Wert einer Variablen wird zunächst immer als Zeichenkette abgespeichert.
2.1.1 Zugriff auf den Wert einer Variablen
 
Um auf den Wert einer Variablen zugreifen zu können, wird das $-Zeichen verwendet. Sie haben sicherlich schon das ein oder andere Mal Folgendes in einer Shell gesehen:
you@host > echo $HOME
/home/you
Hier wurde die Umgebungsvariable HOME auf dem Bildschirm ausgegeben (mehr zu Umgebungsvariablen weiter unten, siehe Abschnitt 2.7). Ebenso wie die Umgebungsvariable HOME können Sie auch eine eigene Benutzervariable definieren und darauf zurückgreifen.
you@host > ich=juergen
you@host > echo $ich
juergen
Soeben wurde eine Benutzervariable »ich« mit dem Wert »juergen« definiert. Mithilfe des $-Zeichens können Sie jetzt jederzeit wieder auf den Wert dieser Variablen zurückgreifen – natürlich nur während der Lebensdauer des Scripts oder der Shell. Sobald Sie ein Script oder eine Shell-Sitzung beenden, wird auch die Variable »ich« wieder verworfen.
2.1.2 Variablen-Interpolation
 
Selten werden Sie eine Variable ausschließlich zur Wiederausgabe definieren. In der Praxis setzt man Variablen meistens in Verbindung mit Befehlen ein.
# Ein einfaches Backup-Script
# Name : abackup
# datum hat die Form YYYY_MM_DD
datum=$(date +%Y_%m_%d)
# Ein Verzeichnis in der Form backup_YYYY_MM_DD anlegen
mkdir backup_$datum
# Alle Textdateien aus dem Heimverzeichnis sichern
cp $HOME/*.txt backup_$datum
Hier haben Sie ein einfaches Backup-Script, mit dem Sie sämtliche Textdateien aus Ihrem Heimverzeichnis in einen neuen Ordner kopieren. Den Ordnernamen erzeugen Sie zunächst mit
datum=$(date +%Y_%m_%d)
Damit finden Sie das aktuelle Datum in der Form »YYYY_MM_DD« in der Variablen »datum« wieder. Damit sich in »datum« nicht die Zeichenfolge »date« befindet, muss diesem Kommando selbst ein $-Zeichen vorangestellt werden. Nur so weiß die Shell, dass sie der Variablen »datum« den Wert des Ausdrucks – hier dem Kommando – in den Klammern übergeben soll. Daher muss auch das komplette Kommando in Klammern gesetzt werden. Dieser Vorgang wird auch als Kommando-Substitution bezeichnet, was allerdings in dieser Form (mit der Klammerung) nur unter der Bash und Korn-Shell, nicht aber unter der Bourne-Shell funktioniert. Bei der Bourne-Shell müssen Sie hierfür die Backticks-Zeichen (`) statt der Klammerung verwenden (mehr zur Kommando-Substitution in Abschnitt 2.4). Testen Sie einfach das Kommando date in gleicher Form in der Shell, um zu verstehen, was hier gemacht wird.
you@host > date +%Y_%m_%d
2005_02_03
In der nächsten Zeile erzeugen Sie dann ein Verzeichnis mit dem Namen backup_YYYY_MM_DD. Hier wird der Verzeichnisname mit einer Variablen-Interpolation interpretiert.
mkdir backup_$datum
Zum Schluss kopieren Sie dann alle Textdateien (mit der Endung ».txt«) aus dem Heimverzeichnis, welches hier mit der Umgebungsvariable HOME angegeben wurde, in das neu erzeugte Verzeichnis backup_YYYY_MM_DD.
cp $HOME/*.txt backup_$datum
So oder ähnlich werden Sie Benutzervariablen sehr häufig verwenden. Das Script bei der Ausführung:
you@host > ./abackup
you@host > ls
abackup
datei1.txt
datei2.txt
datei3.txt
datei4.txt
backup_2004_12_03
backup_2005_01_03
backup_2005_02_03
you@host > ls backup_2005_02_03
datei1.txt datei2.txt datei3.txt datei4.txt
Hinweis für Anfänger Sofern Sie das ein oder andere noch nicht ganz genau verstehen, ist das nicht weiter schlimm, da es hier lediglich um den Zugriff von Variablen geht. Wenn Sie verstanden haben, wann bei der Verwendung von Variablen das Zeichen $ benötigt wird und wann nicht, genügt dies vorerst. Dennoch hat es sich immer wieder bewährt, die Option set -x zu verwenden. Damit bekommen Sie das ganze Script auch noch im Klartext ausgegeben. Dies hilft beim Lernen der Shellscript-Programmierung enorm (dies kann man gar nicht oft genug wiederholen).
|
Nicht definierte Variablen
Verwenden Sie eine nicht definierte Variable in Ihrem Script, bspw. zur Ausgabe, wird eine leere Zeichenkette ausgegeben. Wohl kaum einer wird allerdings eine nicht definierte Variable im Shellscript benötigen. Damit die Shell diesen Umstand bemängelt, können Sie die Option –u verwenden. Dann bekommen Sie einen Hinweis, welche Variablen nicht besetzt sind. Hier ein solches Beispiel.
# Eine nicht definierte Variable wird verwendet
# Name : aerror
# var1 wird die Zeichenfolge 100 zugewiesen
var1=100
# var2 bekommt denselben Wert wie var1
var2=$var1
# var3 wurde nicht definiert, aber trotzdem verwendet
echo $var1 $var2 $var3
Hier wird bei der Ausgabe mittels echo versucht, den Inhalt einer Variablen namens var3 auszugeben, welche allerdings im Script gar nicht definiert wurde.
you@host > ./aerror
100 100
Trotzdem lässt sich das Script ohne Probleme interpretieren. Selbiges soll jetzt mit der Option –u vorgenommen werden.
you@host > sh -u ./aerror
./aerror: line 10: var3: unbound variable
Variablennamen abgrenzen
Soll der Variablenname innerhalb einer Zeichenkette verwendet werden, müssen Sie diesen mit geschweiften Klammern abgrenzen. Ein Beispiel, was hiermit gemeint ist:
# Variablennamen einbetten bzw. abgrenzen
# Name : embeed
file=back_
cp datei.txt $filedatei.txt
Beabsichtigt war bei diesem Script, dass eine Datei namens datei.txt kopiert wird. Der neue Dateiname sollte dann back_datei.txt lauten. Wenn Sie das Script ausführen, findet sich allerdings keine Spur einer solchen Datei. Dem Problem wollen wir auf den Grund gehen. Sehen wir uns das Ganze im Klartext an:
you@host > sh -x ./embeed
+ file=back_
+ cp datei.txt .txt
Hier scheint die Variablen-Interpolation versagt zu haben. Statt eines Dateinamens back_datei.txt wird nur der Dateiname .txt verwendet. Der Grund ist einfach: Die Shell kann nicht wissen, dass Sie mit $filedatei.txt den Wert der Variablen »file« verwenden wollen, sondern sucht hier nach einer Variablen »filedatei«, was – wie Sie ja bereits wissen –, wenn diese nicht definiert wurde, ein leerer String ist. Dieses Problem können Sie umgehen, indem Sie den entsprechenden Variablennamen mit geschweiften Klammern abgrenzen.
# Variablennamen einbetten bzw. abgrenzen
# Name : embeed2
file=back_
cp datei.txt ${file}datei.txt
Jetzt klappt es auch mit back_datei.txt. Die Schreibweise mit den geschweiften Klammern können Sie natürlich grundsätzlich verwenden (was durchaus gängig ist), auch wenn keine weitere Zeichenkette mehr folgt. Gewiss gibt es auch Ausnahmefälle, in denen man keine geschweiften Klammern benötigt, bspw. $var/keinvar, $var$var1, keinevar_$var usw. Aber ein sauberer Stil ist es trotzdem, diese zu verwenden.
Löschen von Variablen
Wenn Sie eine Variable löschen wollen, können Sie dies mit unset erreichen. Wollen Sie hingegen nur den Wert der Variable löschen, aber den Variablennamen selbst definiert lassen, reicht ein einfaches var= ohne Angabe eines Wertes aus. Hier ein Beispiel dazu im Shell-Prompt:
you@host > set -u
you@host > ich=juergen
you@host > echo $ich
juergen
you@host > unset ich
you@host > echo $ich
bash: ich: unbound variable
you@host > ich=juergen
you@host > echo $ich
juergen
you@host > ich=
you@host > echo $ich
you@host > set +u
Wert als Konstante definieren
Wollen Sie einen konstanten Wert definieren, der während der Ausführung des Scripts oder genauer der Shell nicht mehr verändert werden kann, können Sie vor dem Variablennamen ein readonly setzen. Damit versehen Sie eine Variable mit einem Schreibschutz. Allerdings lässt sich diese Variable zur Laufzeit des Scripts (oder genauer der (Sub-)Shell) auch nicht mehr mit unset löschen.
you@host > ich=juergen
you@host > readonly ich
you@host > echo $ich
juergen
you@host > ich=john
bash: ich: readonly variable
you@host > unset ich
bash: unset: ich: cannot unset: readonly variable
Hinweis Bei der Verwendung von readonly handelt es sich um eine Zuweisung! Daher erfolgt auch das Setzen des Schreibschutzes ohne das Zeichen $.
|
Ihre Meinung
Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.
|