MultiTOS für Einsteiger Teil 6 - MultiTOS goes UNIX Teil II

Ich hoffe. Sie haben sich inzwischen vom letzten Kursteil erholt und die Mengen an unverständlichem "UNIX-Kauderwelsch" halbwegs verdaut. Diesmal wollen wir dem Nebel in Sachen Environment und Script-Programmierung ein wenig zu Leibe rücken. Rekapitulieren wir: Ein Script ist eine ASCII-Datei, die Befehle für eine Shell enthält. So ein Script wird Zeile für Zeile abgearbeitet, beinahe so, als ob die Befehle direkt von der Tastatur kommen würden. Aber mit dieser einfachen Darstellung tun wir unserem Mini-UNIX zutiefst unrecht, denn die Script-Sprache ist eigentlich ein komplettes Programmiersystem mit unendlich vielen Anwendungsmöglichkeiten - eben eine mächtige Programmiersprache ...

Wie schon erwähnt, werden verschiedene Scripts auch gleich beim Starten einer UNIX-Shell automatisch ausgeführt, etwa um Anpassungen an den Benutzer bzw. die Rechnerumgebung durchzuführen. Es führt also kein Weg an ihnen vorbei.

Bewaffnen Sie sich nun mit einem ASCII-Editor, wir schreiben das erste Script-Programm!

Den Befehl "ls" zum Anzeigen von Inhaltsverzeichnissen haben wir ja schon kennengelernt. Angenommen, Sie möchte nun immer wieder das Inhaltsverzeichnis von ,,/BIN" und ,/USR/BIN" anschauen, um zum Beispiel einen Überblick über die externen Befehle zu haben. Ohne Script müßten Sie zu diesem Zweck immer wieder die beiden Zeilen "Is /BIN" und ls J USR/BIN" eintippen. Als bequemer Mensch können Sie diese Zeilen problemlos in einem Script-Programm zusammenfassen. Dazu tippen Sie in einem beliebigen ASCII-Editor noch einmal die beiden Zeilen, sicherheitshalber gefolgt von einer Leerzeile, ein und speichern die Datei im Heimatordner ("U:/USR/HOME") unter dem Namen "befehle.ksh" ab.

    # Das erste Script-Programm 
    ls /BIN 
    ls /USR/BIN

Die Endung ".ksh" signalisiert der Korn-Shell, daß es sich bei dieser Datei um ein Script handelt (für die Bourne-Shell würde die Endung " sh" und für die C-Shell ".csh" lauten).

Um das erzeugte Script-Programm zu verwenden, starten Sie Ihre Shell, und vergewissern Sie sich, daß Sie sich im Ordner ,/USR/HOME" befinden. Geben Sie in der Kommandozeile einfach "befehle" ein, gefolgt von einem Druck auf die Taste Return, und schon sehen Sie den Inhalt der beiden Ordner.

Mächtig prächtig, damit ist die prinzipielle Arbeitsweise eines Script-Programmes geklärt und wir können tiefer in die Script-Programmierung abtauchen.

Das Environment

Halt, Kommando zurück, ganz so schnell geht es nicht; denn bevor wir auf die weiteren Befehle der Shell hechten, ist noch etwas Grundlegendes in Sachen UNIX-Shells und damit auch der Script-Programmierung zu besprechen: das Environment und seine Variablen.

Genau wie unter "echtem" UNIX steht einem Programm (also auch einer Shell bzw. einem Script) unter TOS/MiNT/ MTOS ein gewisser Speicherbereich zur Verfügung, in dem diverse Variablen abgelegt werden können. Das Ganze nennt sich auf gut englisch Environment und die Variablen daher Environment-Variablen. Als (deutsche) Übersetzung für Environment paßt in diesem Zusammenhang wohl der Begriff Umgebung am besten. Die Variablen in dieser Umgebung können zum einen Auskünfte über die Systemumgebung geben (z.B. PATH), zum anderen aber auch genau wie die Variablen in einer klassischen Programmiersprache (z.B. BASIC) als Platzhalter für Berechnungen usw. Verwendung finden.

Der Gag an diesem Environment ist die Vererbung! Sie erinnern sich noch an die Vater-/Sohn-Beziehungen von Programmen unter MiNT/MTOS? Wenn nun das Vater-Programm ein Sohn-Programm startet, erbt der Sohn das Environment des Vaters und damit natürlich auch dessen Variablen. Wenn Sie also für das erste Programm in Ihrer MiNT/MTOS-Installation zum Beispiel die Environment-Variable PATH setzen, erben alle weiteren Programme, die vom Erstling zukünftig gestartet werden, eben das Environment und damit auch PATH.

Da unter MiNT/MTOS wie unter UNIX Vater und Sohn (und auch noch die Enkel) gleichzeitig "werkeln" können, kann es natürlich nicht angehen, daß Änderungen, die der Sohn an seinem Environment durchführt, ohne weiteres auf das Environment von Papi durchschlagen. Daher wird bei der Vererbung für den Sohn eine Kopie des väterlichen Environments angelegt, in dem sich das Söhnchen nach Belieben austoben kann, ohne Papi zu belästigen. Eigentlich handelt es sich also um gar keine Vererbung, sondern um die wundersame Vermehrung, aber das ist ein anderes Thema...

Was hat nun diese Erbschleicherei mit der Script-Programmierung zu tun? Vereinfacht gesagt, ist ein Script im Normalfall (Sonderfälle kommen später) der Sohn einer Shell und erbt damit deren Environment (eigentlich ist es so, daß intern noch einmal eine Shell gestartet wird, die das Script bearbeitet). Nur über den "export"-Befehl (dazu mehr im nächsten Kursteil) kann ein Script das Environment der Shell ändern. Dieser Umstand ist sehr wichtig und wird uns noch öfter beschäftigen.

Sodele (wie der Schwabe zu sagen pflegt), damit sind die Environment-Verhältnisse geklärt; wie werden nun das Environment und dessen Variablen angesprochen?

Die Environment-Variablen

Zum Setzen der Variablen genügt eine simple Zuweisung. Geben Sie in der Kommandozeile zum Beispiel folgenden Befehl ein:

TEST=Juchu

Damit haben Sie schon die Variable TEST mit dem Inhalt Juchu" erzeugt. Grundsätzlich können Environment-Variablen nur Text enthalten! Der Befehl "TEST-= 123" erzeugt also keine numerische Variable. sondern einfach einen String mit den Buchstaben "123". ACHTUNG! Die Namen der Environment-Variablen sind "case sensitiv", will sagen, die Groß- bzw. Kleinschreibung ist wichtig, so ist "test" eine andere Variable als "TEST" oder auch als "Test"! Unter UNIX ist es allerdings üblich, die Namen der Environment-Variablen prinzipiell groß zu schreiben.

Sehr schön, und wie fragen wir die Variable TEST wieder ab? Mutige Zeitgenossen können einfach den Befehl "set" verwenden, er gibt am Bildschirm eine Liste mit allen aktuellen Environment-Variablen aus. Nicht erschrecken, die Liste ist etwas länger:

Die Liste der Environment-Variablen:

    ACCEXT=ATT,ATX 
    ACCPATH=C:\,C:\ACCS\ 
    COLUMNS=80 
    ENV=/usr/home/kshrc.ksh 
    GEMEXT=PRG,APP,GTP 
    HISTFILE=/usr/home/history.sh 
    HISTSIZE=50 
    HOME=/usr/home 
    IFS=
    MAILCHECK=600
    MiNT_VERSION=1.8
    OLDPWD=/c/multitos/unix/bin
    OPTIND=1
    PATH=. :/bin:/usr/bin
    PPID=0
    PS1=[$PWD]:
    PS2="
    PS3=#?
    PWD=/usr/home
    RANDOM=8683
    ROWS=25
    SECONDS=52
    SHELL=/bin/sh.ttp
    SHPRINT=C:ÖMULTITOSÖLPR APP
    SHSHOW=C:ÖMULTITOSÖVIEWER.APP
    TEMP=/usr/temp/
    TERM=tw52

Natürlich können die Environment-Variablen auch einzeln abgefragt oder verwendet werden. Zur Abfrage ist der Shell-Befehl "echo" recht nützlich, er entspricht dem BASIC-Befehl "PRINT". Die Zeile

echo $TEST

führt zur Ausgabe von "Juchu" auf dem Bildschirm. Ist Ihnen an der Befehlszeile etwas aufgefallen? Richtig, vor dem Namen der Variablen steht das Zeichen $. Dieses Dollarzeichen ist bei der Verwendung von Environment-Variablen sehr wichtig, denn die Befehlszeile

echo TEST

führt schlicht zur Ausgabe von "TEST" auf dem Bildschirm. Erst das Voranstellen von $ teilt der Shell mit, daß sie eine Environment-Variable ansprechen soll. Der Grund für die unterschiedliche Behandlung von Variablennamen beim Anlegen und Abfragen liegt darin, daß nicht der Befehl "echo" den Inhalt von "TEST" ausliest, sondern bereits die Shell aus "$TEST" ein "Juchu" macht und nur das "Juchu" an den Befehl "echo" weiterreicht. Würde die Shell bereits aus "TEST" ein ,Juchu" machen, könnte, solange diese Variable existiert, nie der Text "TEST" via "echo" ausgegeben werden. Naja, zugegeben, diese Argumentation kann man auch umdrehen, denn solange die Variable "TEST" existiert, kann bei dieser Vorgehensweise eigentlich nie der Text "$TEST" ausgegeben werden, da die Shell immer "Juchu" daraus macht. Aber kein Panik, dafür gibt es natürlich auch einen Weg, setzen Sie den Text einfach in Hochkommata. Die Zeile

echo '$TEST’

gibt ordnungsgemäß "$TEST" auf dem Bildschirm aus. Für den Einsteiger hört sich das zwar zunächst kompliziert an, es hat allerdings den Vorteil, daß sich die einzelnen Befehle wie "echo" oder "ls" usw. überhaupt nicht um diese Interpretation kümmern müssen und damit schön kompakt bleiben.

Sehr schön, aber da ist noch ein Problem: Die Zeile

TEST=Hier ist ein Computer

führt zu einer Fehlermeldung der Shell. Sie beschwert sich, mit "ist" nichts anfangen zu können. Warum nun dieses? Die Shell wertet ein Leerzeichen als das Ende eines Parameters und denkt sich daher, daß mit "ist" ein neuer Parameter/Befehl beginnt, und der ist ihr unbekannt und daher sehr verdächtig. Aber mit Hilfe der Anführungsstriche " können wir auch diesen Haken umgehen. Geben wir folgendes ein:

TEST="Hier ist ein Computer"

Dann handelt die Shell wie gewünscht und legt den ganzen Text "Hier ist ein Computer" in der Variablen TEST ab.

Zusammenfassend gilt folgendes: 1. NAME=XYZ setzt den Wert der Variablen NAME auf XYZ 2. $NAME holt den Inhalt der Variablen NAME 3. Das Setzen eines Textes in Hochkommata verhindert jede Interpretation desselben. 4. Das Setzen eines Textes in Anführungsstriche verhindert das Abbrechen an Leerzeichen, aber nicht die Interpretation!

Mit diesem Wissen könnten wir nun unser erstes Script-Programm etwas flexibler gestalten. Wenn wir zum Beispiel nicht immer den Inhalt von "/BIN" bzw. "/USR/BIN" sehen wollen, sondern sich die zu besichtigenden Ordner hin und wieder ändern, könnten wir zwei Environment-Variablen verwenden. Erweitern wir "befehle.ksh" also um die Variablen "O1" und "O2":

# Das erweiterte Script:
ls $O1
ls $O2

Bevor wir "befehle.ksh" verwenden können. müssen wir erst noch "O1" und "O2" mit sinnvollen Werten besetzen. Für den ersten Aufruf müssen wir also folgende drei Kommandozeilen eingeben:

O1=/BIN
O2=/USR/BIN
befehle

Bei jedem weiteren Aufruf von "befehle" können wir uns das Setzen von "O1" und "02" schenken; nur wenn Sie den Inhalt eines anderen Ordners überwachen möchten, ändern Sie den Wert einer der beiden Variablen.

Zugegeben, unser erstes bzw. zweites Script ist noch nicht unbedingt die Ausgeburt an Nützlichkeit, aber noch stehen wir ja ganz am Anfang, z.B. fehlt uns bisher noch die Möglichkeit. Parameter an unsere Scripts zu übergeben.

Parameterübergabe

Abgesehen von den eben "erschlagenen" selbstdefinierten Variablen, die z.B. mit "set" ausgegeben werden können, stellen UNIX-Shells noch eine Reihe von vordefinierten Variablen zur Verfügung. Deren Inhalt ist vorgegeben und sollte bzw. kann nur abgefragt werden:

Die wichtigsten "eingebauten" Variablen der Shell:

$0 der Name des Scripts
$1 der 1. Parameter
$2 der 2. Parameter
$3 der 3. Parameter .
.
.
$9 der 9. und letzte Parameter; werden mehr Parameter benötigt, kommt der Befehl "shift" zum Einsatz
$* alle Parameter als eine Zeichenkette "$1 $2....$9"
$§ alle Parameter als Reihe von Zeichenketten $1 $2...
$# die Anzahl der übergebenen Parameter
$? der Rückgabewert (ERRORLEVEL) des letzten Befehls

Zum Experimentieren mit der Parameterübergabe hier das Script-Programm "para.ksh":

# Script zur Parameterübergabe: 
echo "Name $0" 
echo "Anzahl der Parameter $#" 
echo "Parameter 1 -> $1" 
echo "Parameter 2 -> $2" 
echo "Parameter 3 -> $3" 
echo "Parameter 4 -> $4" 
echo "Parameter 5 -> $5" 
echo .Parameter 6 -> $6"
echo "Parameter 7 -> $7" 
echo "Parameter 8 -> $8" 
echo "Parameter 9 -> $9"

Starten Sie es mit folgender Kommandozeile:

para Dies ist ein Test

Auf dem Bildschirm sollte folgendes erscheinen:

Name ./para.ksh Anzahl der Parameter 4 
    Parameter 1 -> Dies Parameter 2 -> ist 
    Parameter 3 -> ein Parameter 4 -> Test 
    Parameter 5 -> Parameter 6 -> Parameter 
    7 -> Parameter 8 -> Parameter 9 ->

So einfach ist die Parameterauswertung unter einer UNIX-Shell!

Jedzedle (schon wieder so ein schwäbischer Ausruf) sind wir am Ende angelangt, im nächsten Kursteil wollen wir uns mit Schleifen, Entscheidungen und anderen Strukturen in Script-Programmen beschäftigen. Wenn Sie bis dahin noch ein wenig staunen wollen, probieren Sie doch ei nmal die Kommandozeile "para ." aus.


Richard Kurz
Aus: ST-Computer 02 / 1994, Seite 100

Links

Copyright-Bestimmungen: siehe Über diese Seite