<next ><up><previous><content>


Variablenexpansion

Neben der Ersetzung von Worten, die Jokerzeichen enthalten, durch Dateinamen gibt es noch einen anderen Wortersetzungmechanismus in der Shell. Dieser reagiert auf Worte, die mit einem $ (Dollarzeichen) beginnen, und ersetzt Variablennamen durch ihren Wert.

 

Setzen und Löschen von Variablenwerten

Die UNIX-Shell erlaubt es, Variablen mit Werten zu belegen. Diese Werte können entweder in der Shell selber benutzt werden oder von UNIX-Kommandos aus abgefragt werden. Obwohl der Variablenmechanismus der Shell dem Variablenkonzept von anderen Programmiersprachen recht ähnlich ist, weist er doch einige Besonderheiten auf. So sind zum Beispiel alle Variablen in der Shell Zeichenketten (strings). Nur in Ausnahmefällen werden diese Zeichenketten als Zahlen oder logische Werte interpretiert.

Einer Shellvariablen wird mit einer einfachen Zuweisung ein Wert zugewiesen.

 

Figure:
Zuweisung von Werten an Variablen
 

Dabei ist es wichtig, die Zuweisung selbst ohne Leerzeichen vor und hinter dem Gleichzeichen zu schreiben. Dies ist eine echte Ausnahme: Während in der Shell sonst überall Leerzeichen als Worttrenner notwendig sind, muß eine Zuweisung von der Shell als ein Wort gelesen werden.

Mit dem Shellkommando set ohne weitere Parameter kann man abfragen, welche Variablen zur Zeit in der Shell gesetzt sind und welche Werte diese haben. Bei einer großen Anzahl von Variablen kann es sinnvoll sein, die Ausgabe von set durch einen Pager (etwa more) oder durch einen Suchbefehl (etwa grep) zu leiten.

 

Figure:
Abfrage von Variablenwerten
 

Wie fast überall in UNIX sollte man auf die Groß- und Kleinschreibung der Namen achten. Auch bei Variablennamen unterscheidet UNIX die Schreibweise.

[ top ]

 

Gebrauch von Variablen

In der Shell können Variablen an jeder Stelle verwendet werden. Immer wenn die Shell bei der Analyse einer Kommandozeile ein Wort findet, das mit dem Zeichen $ (Dollar) beginnt, so schneidet sie das betreffende Wort aus und ersetzt es durch den Wert der entsprechenden Variablen. Wenn die benannte Variable nicht definiert ist, wird nichts eingesetzt.

 

Figure:
Wortersetzung bei Variablen
 

In Variablen kann man so Kurzschreibweisen für häufig benutzte Verzeichnisse oder Kommandos speichern oder Konfigurationsinformationen für Befehle hinterlegen. Viele UNIX-Befehle fragen die Werte von bestimmten Variablen ab und verhalten sich je nach Wert, der in der Variablen hinterlegt ist, unterschiedlich. Man kann so das Verhalten der eigenen Arbeitsumgebung in gewissen Grenzen konfigurieren.

Eine Variable wird mit dem Kommando unset gelöscht. Weist man der Variablen dagegen nichts zu (also den leeren String), so ist der Wert der Variablen zwar leer, aber die Variable selbst ist noch definiert. Wir werden später sehen, daß dies einen Unterschied machen kann.

 

Figure:
Unterschied zwischen leeren und gelöschten Variablen
 

[ top ]

 

Exportieren und Schützen von Variablen

Damit ein UNIX-Kommando eine Variable abfragen kann, muß diese Variable zunächst einmal exportiert werden. Per Voreinstellung sind nämlich die Werte aller Variablen lokal zu der aktuellen Kommandoshell. Nur diejenigen Variablen, die für den Export markiert sind, werden an Untershells und von der aktuellen Shell gestartete Kommandos weitervererbt.

Man markiert Variablen mit dem Befehl export <varname> für den Export. Derartig markierte Variablen werden an alle Unterprozesse weitervererbt und können dort abgefragt werden. Mit dem Kommando env oder (je nach UNIX-Version) printenv kann man eine Liste der für den Export markierten Variablen und ihrer Werte bekommen.

 

Figure:
Definition und Export einer Variablen
 

Eine exportierte Variable wird mit dem Kommando unset nicht nur gelöscht, sondern ist bei erneuter Zuweisung automatisch wieder eine lokale Variable (also nicht exportiert).

Mit dem Schlüsselwort readonly kann man Variablen in Konstanten verwandeln. Der Wert einer solchen Variablen kann dann nicht mehr geändert werden. readonly ohne Parameter zeigt eine Liste der Konstanten an.

[ top ]

 

Besondere Variablen

Einige Variablen haben in UNIX per Konvention eine besondere Bedeutung. Manche dieser Variablen sind in die Shell eingebaut, d.h. sie verändern ihren Wert automatisch, andere haben nur deswegen eine besondere Bedeutung, weil sie von gängigen UNIX-Kommandos abgefragt werden.

Vordefinierte Variablen mit fester Bedeutung sind zum Beispiel die folgenden Variablen:

 

$0
Die Variable $0 enthält den Namen des aufgerufenen Befehls, also bei einem Shellscript den Namen der Scriptdatei.

 

$1 bis $9
Die Variablen $1 bis $9 enthalten die Parameter 1 bis 9 des Aufrufes. Wurde das Kommando mit mehr als 9 Parametern aufgerufen, so sind die weiteren Parameter nicht direkt ansprechbar. Sie können aber mit dem Shell-Kommando shift in den Zugriff gebracht werden.

Die Variablen $1 bis $9 in der UNIX-Shell finden sich als die Variablen %1 bis %9 direkt und mit derselben Bedeutung in MS-DOS wieder. Auch in MS-DOS ist es möglich, mit einem shift auf weitere Parameter zuzugreifen.

 

$*
Manchmal möchte man jedoch auf alle Parameter der Kommandozeile als ein zusammenhängendes Wort zugreifen können. Dies ist mit der Variablen $* möglich. Sie entspricht also der Konstruktion ''$1 $2 $3 ... ''. $* entspricht auch dann allen Parametern der Kommandozeile, wenn dies mehr als 9 Stück sind.

 

$@
Seltener möchte man alle Parameter der Kommandozeile als eine Folge von einzelnen Worten im Zugriff haben. Die Konstruktion $@ entspricht ''$1'', ''$2'', ''$3'', ... Beachten Sie den Unterschied zu $*!

 

$#
Die Shell vermerkt in der Variablen $# die Anzahl der Parameter eines Kommandos.

 

$-
In der speziellen Variablen $- speichert die Shell die derzeit eingeschalteten Optionsbuchstaben.

 

$?
Jedes UNIX-Kommando hinterläßt seinem Aufrufer bei seiner Beendigung eine Zahl, den sogenannten Exit-Status. Sie kann dem Aufrufer Auskunft darüber geben, ob das Kommando normal beendet worden ist oder ob bei seiner Bearbeitung ein Problem auftrat. Per Konvention bedeutet ein Exit-Status von 0, daß das Kommando fehlerfrei abgearbeitet worden ist; jeder andere Exit-Status bedeutet eine in irgendeiner Form fehlerhafte Abarbeitung des Befehls. Welche Bedeutung ein Fehlercode genau hat, hängt natürlich vom Befehl ab.

In der Shell-Variablen $? kann man den Endestatus des zuletzt ausgeführten Befehls abfragen.

 

$$
In einer UNIX-Shell wird jedes Kommando als ein eigener Prozeß ausgeführt. Jeder Prozeß ist dabei durch seine Prozeßnummer von allen anderen Prozessen zu unterscheiden; Prozeßnummern sind also zu einem gegebenen Zeitpunkt eindeutig.

Die Prozeßnummer der eigenen Shell steht in der Variablen $$ zur Verfügung. Diese Variable wird oft verwendet, wenn man eindeutige Dateinamen für Zwischendateien erzeugen möchte.

 

Wenn das Script im Beispiel gif zum selben Zeitpunkt von mehr als einem Benutzer aufgerufen wird, verwenden alle Instanzen des Scriptes denselben Dateinamen /tmp/datei. Würde man diesen festen Dateinamen zur Erzeugung von Zwischendateien verwenden, so würden alle Instanzen des Scriptes dieselbe Zwischendatei verwenden und sie so gegenseitig überschreiben. Definiert man den Namen der Zwischendatei dagegen als $0.$$, so wird für $0 der Name des Scriptes eingesetzt und für $$ die aktuelle Nummer dieses Prozesses. Da jede Instanz eines Scriptes eine eigene Prozeßnummer hat, würde jede dieser Instanzen also auch einen anderen Zwischendateinamen verwenden (etwa probe.1704 und probe.1706).

 

$!
Unter diesem Namen ist die Prozeßnummer des letzten erzeugten Hintergrundprozesses verfügbar.

 

Andere Variablen haben deswegen eine spezielle Bedeutung, weil viele Programme sie abfragen oder sie schon beim Login eines Benutzers automatisch mit Werten belegt werden.

 

$EDITOR
Viele UNIX-Programme verwenden einen Editor, wenn der Benutzer größere Mengen Text eingeben muß. Ist die Variable $EDITOR nicht gesetzt, wird der Standardeditor vi verwendet. Da die meisten Menschen den Editor vi nicht verwenden mögen, geben sie in der Variablen $EDITOR ihren Editor mit vollem Pfadnamen an. Die meisten Programme verwenden dann diesen Editor anstelle des vi.

 

$HOME
In der Variablen $HOME ist der Name des Home-Verzeichnisses des aktuellen Benutzers gespeichert. Wenn man das Kommando cd ohne Parameter verwendet, wechselt es in dieses Verzeichnis. Praktisch alle UNIX-Kommandos erwarten Konfigurationsdateien als Punkt-Dateien in diesem Verzeichnis, wenn sie überhaupt Konfigurationsdateien verwenden.

 

$IFS
Wie ganz am Anfang bemerkt, teilt die Shell eine Kommandozeile an Leerzeichen, Tabulatorzeichen und Returnzeichen in Worte ein, die nachher Kommandos, Parameter, Variablen und so weiter bilden. Welche Zeichen jetzt Trennzeichen zwischen Worten darstellen, ist nicht fest eingestellt, sondern wird anhand der Variablen $IFS entschieden. Die Variable enthält eine Liste von Zeichen, die Trennzeichen zwischen Worten darstellen. Voreingestellt enthält diese Liste genau die Zeichen Leerzeichen, Tabulator und Zeilenende.

 

$MAIL,
 
$MAILCHECK,
 
$MAILMSG
UNIX überprüft alle $MAILCHECK Sekunden, ob neue Nachrichten in der durch $MAIL bezeichneten Datei angekommen sind. Falls dies der Fall ist, wird der Text $MAILMSG ausgegeben. $MAIL sollte normalerweise den vollen Pfadnamen der eigenen Maildatei enthalten, also üblicherweise /usr/spool/mail/<username> oder /usr/mail/<username>, je nachdem, wie das lokal geregelt ist. $MAILCHECK steht standardmäßig auf einem Wert von 600 Sekunden (10 Minuten), was normalerweise auch ausreichend ist. Setzt man diesen Wert auf 0, so wird vor jeder Kommandoausführung in der Shell (also vor jedem Prompt) eine Überprüfung vorgenommen. Die voreingestellte Nachricht ist ,,You have mail.``.

 

$PAGER
Falls die Umgebungsvariable $PAGER gesetzt ist und den vollen Pfadnamen eines Textanzeigeprogrammes wie pg, more oder less enthält, verwenden einige UNIX-Kommandos (zum Beispiel der man-Befehl) diesen Anzeiger, um größere Mengen an Text anzuzeigen. Ist die Variable nicht gesetzt, so wird cat verwendet, und der Text rauscht ohne Pause durch.

 

$PATH
Wenn man in der UNIX-Shell ein Kommando eingibt, so wird es nacheinander in den in dieser Variablen aufgeführten Verzeichnissen gesucht. Üblicherweise enthält diese Variable eine Liste von Verzeichnissen. Die Namen der Verzeichnisse sind dabei durch jeweils einen Doppelpunkt voneinander getrennt und werden genau in der aufgeführten Reihenfolge durchsucht.

Diese Variable scheint auf den ersten Blick genau dem Pfad von MS-DOS zu entsprechend. Jedoch gibt es einen wichtigen Unterschied: Bei MS-DOS ist das aktuelle Verzeichnis immer automatisch das erste Verzeichnis im Suchpfad. Unter UNIX dagegen muß das aktuelle Verzeichnis ausdrücklich mit dem Namen ''.'' im Suchpfad aufgeführt sein, wenn es auch für Kommandos durchsucht werden soll. Es wird dann auch genau an der angegebenen Position im Suchpfad durchsucht und nicht wie bei MS-DOS immer als erstes Verzeichnis.

Für den UNIX-Systemverwalter ist es aus Sicherheitsgründen eine gute Idee, das aktuelle Verzeichnis überhaupt nicht im Suchpfad zu haben, oder, wenn doch, dann wenigstens als allerletztes Verzeichnis im Pfad.

 

 

$PS1
Die Abkürzung PS1 steht für Prompt String 1. Der Prompt ist das Bereitschaftszeichen der Shell. Standardmäßig ist es $ für normale Benutzer und # für den Systemverwalter. Viele Systemverwalter setzen sich den aktuellen Pfad, ihren Usernamen und bei Netzwerken auch noch den Namen der Maschine in den Prompt, damit sie auf den ersten Blick erkennen, unter welcher Benutzer-ID und auf welcher Maschine sie gerade arbeiten.

 

$PS2
Wenn eine Fortsetzungszeile angefordert wird, verwendet die Shell den in der Variablen PS2 definierten Promptstring. Standardmäßig steht dieser auf >.

 

$TERM
Bildschirmorientierte Programme müssen wissen, wie sie ein Terminal dazu bringen können, den Bildschirm zu löschen oder den Cursor zu bewegen. Leider müssen unterschiedliche Terminaltypen auf unterschiedliche Weise angesprochen werden. In der Variablen $TERM ist der Name des aktuellen Terminals gespeichert. Programme können diesen Namen abfragen und in der terminal capabilities database, kurz termcap, nachschlagen, wie dieser Terminaltyp nun genau angesteuert wird.

 

$TZ
Ein UNIX-Rechner hat nur eine interne Uhrzeit und diese wird normalerweise in UT (universal time) gespeichert, um eine für alle Benutzer einheitliche Zeitbasis zu haben. Der Benutzer möchte Zeitangaben aber natürlich in der für ihn gültigen und gewohnten Zeitzone haben. Die Angabe in der $TZ-Variablen kann ziemlich kompliziert werden, falls eine Sommerzeit im Spiel ist und man die Umschaltung zwischen Sommerzeit und Winterzeit automatisieren möchte. Im einfachsten Fall enthält die Variable nur den Namen der lokalen Zeitzone und um wieviele Stunden diese Zeitzone von UT abweicht.

In Mitteleuropa gibt man als Zeitzone CET-1 an. Beachten Sie, daß central european time um plus eine Stunde von der UT abweicht, aber minus eine Stunde angegeben werden muß. Das liegt daran, daß UNIX trotz aller Internationalität ein amerikanisches Produkt ist und die eigenen (amerikanischen) Zeitzonen selbstverständlich niemals negativ sein können.

 

$LOGNAME,
 
$USER
Je nach lokaler Konvention befindet sich der Benutzername, unter dem man sich in das System eingeloggt hat, in der Variablen $LOGNAME oder $USER.

 

[ top ]

 

Tricks mit geschweiften Klammern

Manchmal hat man beim Einsatz von Variablen Probleme, zu unterscheiden, wo der Variablenname aufhört und der normale Text des Kommandos wieder beginnt.

 

Figure:
Wo hört der Variablenname auf?
 

In diesem Fall muß man den Namen der Variablen mit geschweiften Klammern einschließen, damit die Shell den Anfang und das Ende des Variablennamens erkennen kann. Man darf diese Einschließung immer machen, aber aus Bequemlichkeit läßt man sie meistens weg.

Wenn eine Variable undefiniert ist, wird sie normalerweise durch nichts ersetzt. Manchmal möchte man das nicht; statt dessen möchte man, daß an Stelle von nichts ein Standardwert eingesetzt wird. Das kann man erreichen, indem man diesen Standardwert in der Form ${varname-standardwert} mit dem Variablennamen zusammen angibt. Der Variablenname ist danach aber immer noch undefiniert.

 

Figure:
Vorgabe von Standardwerten bei der Verwendung von Variablen
 

Verwendet man an Stelle des Minuszeichens ein Gleichheitszeichen, so wird der Standardwert nicht nur ausgegeben, sondern der undefinierten Variablen wird dieser Standardwert in einem Arbeitsgang auch gleich zugewiesen:

 

Figure:
Zuweisung von Standardwerten
 

Wenn kein Standardwert Sinn macht, kann man immerhin noch abfragen, ob eine Variable definiert ist. Ist sie es nicht, wird das laufende Script abgebrochen und mit einer entsprechenden Nachricht beendet.

 

Figure:
Abfrage, ob eine Variable überhaupt definiert ist
 

Und schließlich kann es noch sein, daß man nur testen möchte, ob ein Parameter gesetzt ist.

 

Figure:
Abfrage, ob eine Variable überhaupt definiert ist
 

Im täglichen Leben wird man allenfalls die Möglichkeiten mit dem Minuszeichen und dem Gleichzeichen einmal verwenden. Die beiden anderen Fälle lassen sich mit einem schnellen if wesentlich besser lesbar und leichter verständlich erschlagen.

[ top ]


<next ><up><previous><content>