Variablen heißen in der Shell nicht Variablen, sondern Shellparameter. Da aber in allen anderen Sprachen Variablen halt Variablen heißen, und Parameter die Dinger sind, die man an ein Programm oder an eine Funktion übergibt, werde ich Variablen auch weiterhin so nennen.
Variablen werden in der Shell als Zeichenketten (Strings) gespeichert. Es gibt einfach keine numerischen Variablen. Strukturen (struct, class), oder so etwas wie union oder Record sowieso nicht.
Um eine Variable zu verwenden, schreibt man ein
Dollarzeichen $
, gefolgt vom Variablennamen. Den Wert der Variablen EGON kann
verwenden, indem $EGON
schreibt.
Wenn direkt an den Variablennamen weiterer Text anschließt, kann die Shell
natürlich nicht erkennen, wo der Name nun enden soll. Angenommen, man hat die
Variable BASIS auf den Wert 10 gesetzt, und möchte jetzt mit dem
Ausdruck $BASISE3
den String 10E3
erzeugen, dann wird das nicht klappen, weil die Shell nicht nach dem Namen BASIS sucht, sondern nur nach
BASISE, Als Lösung bietet es sich dann an, den gewünschten Variablennamen
in geschweifte Klammern zu setzen: ${BASIS}E3
liefert tatsächlich 10E3
.
Wenn man eine Variable NAME verwendet, die nicht definiert ist, dann
liefert $NAME
einen leeren String. Insofern sieht man meistens keinen Unterschied zwischen einer Variablen, die gar
nicht gesetzt ist, und einer Variablen, der ein leerer String zugewiesen ist.
Manchmal ist der Unterschied aber von Belang,
siehe Vordefinierte und spezielle Variablen, shift, set.
Eine gänzlich undefinierte Variable
liefert nämlich bei ihrer Verwendung einen
Nullwert, der sich in Ausdrücken manchmal anders verhält als ein leerer
String. Will man eine bereits vorhandene Variable wirklich löschen, so daß sie
den Nullwert liefert, dann
kann man das mit unset machen; Beispiel:
klaus@aw35:~ >
unset NAME
Wenn die Variable vorher gar nicht existiert hatte, schadet der Befehl auch nichts.
Die Parameter eines Skripts lassen sich mit dem (internen) Kommando getopts leichter auswerten als zu Fuß. Das setzt aber voraus, daß die Optionen Unix-üblich vor weiteren Argumenten kommen, und nur aus einem Bindestrich und einem weiteren Buchstaben bestehen (wie beispielsweise bei einem Druckaufruf lpr -c -P lp2 -s datei1 datei2).
Mit getopts lassen sich Parameter verarbeiten, die keine Argumente haben (-c und -s im lpr-Beispiel), oder genau ein Argument haben (-P im lpr-Beispiel). Die restlichen Argumente (hier datei1 und datei2) müssen nach den Optionen kommen, und werden von getopts nicht verarbeitet.
getopts wird mit (mindestens) zwei Argumenten aufgerufen. Das
erste Argument ist ein String, in dem die zu erkennenden Optionen
angegeben sind. Eine Option, die ein zusätzliches Argument erhält,
kennzeichnet man durch einen nachfolgenden Doppelpunkt (:
). Um
die lpr-Optionen für das obige Beispiel zu erkennen, müßte man
also den String "P:cs"
angeben.
Das zweite Argument ist der Name einer Variablen, in der die erkannte Option gespeichert wird (ohne Bindestrich).
getopts liefert mit jedem Aufruf eine weitere Option aus der Parameterliste, und gibt true (also 0) zurück, wenn eine Option gefunden wurde, oder false, wenn keine Option mehr gefunden werden kann.
Wenn eine der Optionen ein weiteres Argument hat (im String mit dem
Doppelpunkt (:
) markiert), dann wird dieses Argument in der
Variablen OPTARG hinterlegt.
Die Parameterliste selbst wird nicht verändert.
#!/bin/sh # Die Optionen -i, -j, -k und -l sollen erkannt werden, # wobei für -k ein Argument angegeben werden muß: while getopts "ijk:l" option do case $option in i) echo Die Option i ;; j) echo die Option j ;; k) echo die Option k mit Argument $OPTARG ;; l) echo die Option l ;; \?) echo falsche Argumente ;; *) echo sollte nicht vorkommen ;; esac doneerhält man beim Aufruf mit den Optionen
-i -k blabla -l
folgende Ausgabe:
Die Option i
die Option k mit Argument blabla
die Option l
getopts muß sich von einem Aufruf zum nächsten merken, wie weit
es die Argumente schon ausgewertet hat. Dazu verwendet es die Variable
OPTIND. Diese wird beim Starten eines Skripts automatisch auf
1
gesetzt, und von getopts bei jedem Aufruf
weiter gezählt. Dies kann man nutzen:
1
, und kann
dann wieder in einer Schleife getopts aufrufen, bis es false liefert.
#!/bin/sh # Die Optionen -i, -j, -k und -l sollen erkannt werden, # wobei für -k ein Argument angegeben werden muß: while getopts "ijk:l" option do case $option in i) echo Die Option i ;; j) echo die Option j ;; k) echo die Option k mit Argument $OPTARG ;; l) echo die Option l ;; \?) echo falsche Argumente ;; *) echo sollte nicht vorkommen ;; esac done # OPTIND hat den Wert (Anzahl der ausgewerteten Parameter)+1. # Diese Argumente brauchen wir schon nicht mehr, und verschieben # deshalb die Argumente um $OPTIND-1 nach unten: shift `expr $OPTIND - 1` # Anzeige der restlichen Parameter: echo $*
Bei einem Aufruf mit den Parametern
-k keinegnade -l blabla abc
erhält man die Ausgabe:
die Option k mit Argument keinegnade
die Option l
blabla abc
Siehe dazu auch
Numerik light mit expr,
while-Schleife,
Vordefinierte und spezielle Variablen, shift, set, und
case.