Home Page
        Bestellung     Downloads     Support     Kontakt     English
ZOC Terminal ist ein professioneller SSH Client und Terminal-Emulator für Windows und macOS.
ZOC Online Hilfe Thema:

Die Programmierung von ZOC (REXX/DDE) → REXX Sprachelemente

Diese Übersicht behandelt spezielle Themen über die Kontrollsprache REXX (alternativ ist eine allgemeiner gehaltene ZOC REXX-Einführung unter REXX Programmierung zu finden).

Die REXX Sprache für ZOC besteht im Prinzip aus drei Teilen:
1. REXX Grundbefehle (IF, LOOP, CALL, usw.)
2. REXX Standardfunktionen. (TIME(), SUBSTR(), STRIP(), usw.)
3. ZOC Erweiterungen (ZocSend, ZocDownload, ZocWait, etc.)

 

Der Text unten beschreibt den Grundumfang (Punkte 1 und 2). Die speziellen ZOC-Erweiterungen (Punkt 3) sind unter Hilfe-Menü→ZOC REXX-Befehle/Funktionen zu finden.

Neben der Beschreibung hier, ist der komplette REXX Grundumfang (wiederum Punkte 1. und 2.) auch an verschiedenen Stellen im Internet beschrieben. Links hierzu befinden sich im Rexx-Ordner innerhalb des Ordners ZOC Dateien (wir empfehlen das REXX Wiki (deutsch)).

Die ZOC REXX Reference (PDF, engl) deckt alle drei Punkte ab. Die unten aufgeführten Themen werden außerdem in den REXX-Beispielen gezeigt, die über den REXX Link im o.g. Ordner bzw. in der REXX Online Dokumentation verfügbar sind.

       
Programm-Formatierung
 

Alle REXX-Programme müssen prinzipiell mit einem Kommentar beginnen. Als Kommentar gilt Text, der zwischen /* und */ steht. Außerdem gibt es Zeilenkommentare, die durch -- eingeleitet werden und bis zum Ende der Zeile gelten.

Es können mehrere Befehle in eine Zeile geschrieben werden, wenn diese durch Komma voneinander getrennt werden. Ein Befehl kann in der nächsten Zeile fortgesetzt werden, wenn am Ende der vorherigen Zeile ein zusätzliches Komma geschrieben wird.
 

/* REXX */
    
SAY "Hello "; SAY "World"
CALL zoc "REQUEST", "Wie geht's", ,
     "Gut", "Nicht schlecht"
answer= ZOCRESULT()
-- jetzt ist genug
EXIT

Zahlen und Berechnungen
 

Zahlen können zum Rechnen, Zählen usw. verwendet werden. REXX verwendet Zahlen und Berechnungen in einer denkbar unkomplizierten Weise:
 

/* REXX */
SAY 4*5+3*5 /* Ausgabe: 35 */
SAY 10/3 /* Ausgabe: 3.333333 */
SAY 10%3 /* Ausgabe: 3 (Ganzzahl-Division) */
SAY 10//3 /* Ausgabe: 1 (Divisions-Rest) */
N= 4
SAY N /* Ausgabe: 4 */
N= N+1
SAY N*3 /* Ausgabe: 15 */

Zeichenketten
 

Obwohl REXX in der Lage ist, mit Text ohne Anführungszeichen zu arbeiten, ist es generell besser, Zeichenketten mit einfachen oder doppelten Anführungszeichen zu versehen:
 

/* REXX */
SAY "Hello World!"
SAY "Joe's Bar"
SAY 'Er sagt: "Verwende ZOC!"'
SAY 'Sie sagt: "Mach ich sowieso schon!"'

Zeichenketten können Variablen zugewiesen werden. Außerdem können Zeichenketten und Variablen direkt aneinandergereiht werden. Falls syntaktisch notwendig kann auch der String-Verbindungsoperator || verwendet werden:
 

/* REXX */
w= "World"
ex= "!"
w2= w||ex -- the || operator is actually required here (w||ex vs. wex)
hwe= "Hello "w2
    
-- fuenf mal "Hello World!"
SAY hwe
SAY "Hello" w2
SAY "Hello "w2
SAY "Hello "||w2
SAY "Hello "||w||ex

Ablaufverfolgung
 

Zur Fehlersuche ist es möglich, am Anfang des Programms nach der ersten Zeile den Befehl TRACE A anzugeben. Danach zeigt der REXX-Interpreter jeden Befehlsschritt vor der Ausführung an. TRACE I zeigt eine sehr detaillierte Ablaufverfolgung, TRACE O schaltet die Ablaufverfolgung wieder aus.

Vergleiche
 

Um Vergleiche in REXX auszudrücken, stehen folgende Vergleichs-Operatoren zur Verfügung:

Operator Funktion Beispiel
= Numerische Gleichheit IF ret=640 THEN …
== Gleichheit bei Zeichenketten IF input=="ZOC" THEN …
<> nicht gleich IF rc<>640 THEN …
\= nicht gleich (wie <>) IF rc\=640 THEN …
< kleiner als IF val<10 THEN …
> größer als IF val>50 THEN …
<= kleiner oder gleich IF val<=100 THEN …
>= Größer oder Gleich IF val>=100 THEN …
& UND-Verknüpfung IF (i>=0) & (i<10) THEN …
| ODER-Verknüpfung IF (k=0) | (k=1) THEN …
\ NICHT-Verknüpfung IF \(k=0) THEN …

Entscheidungen
 

Entscheidungen werden in der Syntax IF <ausdruck> THEN DO <befehle> END ELSE DO <befehle> END ausgedrückt (siehe Abschnitt Vergleiche (oben) für die Vergleichs- und Verknüpfungsoperationen).

Ein typischer IF-Programmteil sieht in etwa so aus:
 

/* REXX */
IF rc=0 | rc=1 THEN DO /* rc 0 OR rc 1 */
    SAY "ok"
END
ELSE DO
    SAY "failed"
END

Der ELSE-Zweig kann weggelassen werden, wenn er nicht benötigt wird. Die Schlüsselwörter DO und END können weggelassen werden, wenn sich nur ein Befehl zwischen DO und END befindet.
 

/* REXX */
IF rc=0 | rc=1 THEN SAY "ok"
ELSE SAY "failed"

Schleifen
 

Schleifen werden in REXX folgendermaßen formuliert:

DO <zähler> <befehle> END
DO WHILE <bedingung> <befehle> END
DO UNTIL <bedingung> <befehle> END
DO <variable>=<start> TO <ende> <befehle> END


 

/* REXX */
DO 5
    SAY "Hello"
END
    
N= 100
DO WHILE n>0
    SAY n
    n= n-1
END
    
DO i=1 TO 10
    SAY i
END

Schleifen können mit dem Befehl LEAVE abgebrochen werden. Mit ITERATE kann innerhalb der Schleife der nächste Schleifendurchgang ausgelöst werden (d.h. der Befehl überspringt den Rest des aktuellen Schleifendurchgangs).

Sprünge und Prozeduren
 

Sprungmarken und Prozeduren werden mit einem Namen und nachfolgendem Doppelpunkt gekennzeichnet. Um eine Sprungmarke anzuspringen, wird der Befehl SIGNAL verwendet, während der Befehl CALL eine Prozedur aufruft (die Prozedur kann zum Aufrufpunkt mittels RETURN zurückkehren).

Das nachfolgende Beispiel zeigt einen Sprung und einen Prozeduraufruf mit Argumentübergabe:
 

/* REXX */
    
PULL n
    
IF n=0 THEN SIGNAL get_out
    
teny= 10/n
SAY "10/"n "is" teny
    
CALL square n
    
get_out:
    
EXIT
    
square:
    value= ARG(1)
    sqr= value*value
    SAY "Das Quadrat von "||value||" ist "||sqr
    RETURN
    

Funktionsaufrufe
 

Funktionen werden wie Prozeduren gekennzeichnet und aufgerufen. Allerdings besitzen Funktionen im Gegensatz zu Prozeduren einen Rückgabewert:
 

/* REXX */
    
SAY "Basis eingeben"
PULL b
SAY "Exponent eingeben"
PULL p
    
result= power(b,p)
SAY "Der " p "te Exponent von " b " ist " result
    
EXIT
    
power:
    base= ARG(1)
    pow= ARG(2)
    res= 1
    DO I=1 TO pow
     res= res*base
    END
    RETURN res

Externe Skripts
 

Es ist auch möglich ein externes Skript als Unterprogramm oder Funktion aufzurufen. Dazu muss der Name der Datei in Hochkommata geschrieben werden und die Datei entweder im ZOC-Programmordner, im ZOC Dateiordner oder im ZOC Skript-Ordner oder in einem Ordner im Windows Suchpfad (PATH) oder im REGINA REXX Makro Pfad (REGINA_MACROS) liegen. Alternativ kann die Datei komplettem mit Pfad angegeben werden.

Parameter werden wie sonst auch mit Komma getrennt aufgelistet und können im externen Skript mittels der ARG(n) Funktion abgegriffen werden.
 

/* REXX:test.zrx */
    
/* externes Skript in einem der ZOC ordner */
CALL "sub.zrx" "Hello", "World"
    
/* externes Skript in einem anderen Ordner */
CALL "C:\somefolder\sub.zrx" "Hello", "World"
    
/* externes Skript als Funktion */
x= "sub.zrx"(12,2)
SAY x
    
/* externes Skript per INTERPRET */
scriptfile= "Z:\test\zzz.zrx"
cmd= 'CALL "'||scriptfile||'"'
INTERPRET cmd
    
/* externes Skript als Funktion per INTERPRET */
scriptfile= "sub.zrx"
cmd= 'x= "'||scriptfile'"(12,2)'
INTERPRET cmd
SAY x

Das aufgerufene Skript kann die Parameter durch die REXX Funktion ARG(n). aufnehmen und Ergebnisse per RETURN zurückgeben:
 
/* REXX:sub.zrx */
a= ARG(1)
b= ARG(2)
SAY a
SAY b
mult= a*b
RETURN mult

Der PARSE Befehl
 

PARSE ist ein flexibles REXX Kommando um formatierte Zeichen in Teile zu zerlegen und die Teile Variablen zuzuweisen. Der Syntax hierfür ist PARSE VALUE <zeichenkette> WITH <variable>"<trenner>" … Wenn Sie z.B. eine Zeichenkette coord mit Koordinaten in der Form <index>: <pos-x>/<pos-y> haben, können Sie diese leicht mittels

PARSE VALUE coord WITH index": "posx"/"posy zerlegen.
 
Beispiel:

/* REXX BEISPIEL UM EIN MIT KOMMA GETRENNTE LISTE VON ZAHLEN ZU ZERLEGEN */
x= "1, 2, 3, 4"
    
DO FOREVER
    IF x=="" THEN LEAVE
    
    PARSE VALUE x WITH zahl", "rest
    
    SAY zahl
    
    x= rest
END

Verwendung von ZOC-Befehlen
 

ZOC-Befehle sind eine Erweiterung der REXX Sprache in Form von Prozeduren und Funktionen und bieten Zugriff auf ZOC-spezifische Funktionalitäten (siehe ZOC-REXX Befehle).

ZOC-Befehle, die keinen Rückgabewert besitzen (oder wenn Sie an dem Rückgabewert nicht interessiert sind), werden wie Prozeduren aufgerufen:
CALL <zoc-befehlsname> <argument(e)>

ZOC-Befehle, die einen Rückgabewert besitzen, werden wie Funktionen aufgerufen:
<ergebnis>= <zoc-befehlsname>(<argument(e)>)

Verwendung von macOS- oder Windows-Befehlen
 

Befehle, die direkt vom Betriebssystem ausgeführt werden (wie z.B. Löschen und Umbenennen von Dateien), müssen direkt an das Betriebssystem adressiert werden. Dies kann entweder durch REXX's ADDRESS CMD Befehl oder durch ZOC's ZocShell Befehl geschehen.
 

/* REXX */
ADDRESS CMD "cmd.exe /c DEL UPLOAD.TMP"
CALL ZocShell "DEL UPLOAD.TMP"

Eingebaute Funktionen
 

Die nachfolgenden Funktionen können in Zuweisungen oder in anderen Befehlen, die Werte erwarten, verwendet werden, z.B. b= ABS(a) oder IF ABS(n)>10 THEN ….

.Es sind nur die wichtigsten Funktionen und Argumente aufgelistet. Der komplette Sprachumfang ist in der ZOC REXX Reference (PDF, engl) beschrieben, die sich im Ordner Eigene Dateien→ZOC8 Dateien→Rexx befindet.

ABS(<wert>)
 

Absoluter Wert (entfernt Vorzeichen), z.B. n=ABS(t)

ARG(<n>)
 

Liefert das n-te Argument einer Prozedur/Funktion.

COPIES(<str>, <anzahl>)
 

Gibt <anzahl> Kopien von <string> zurück, z.B. x=COPIES("-mehr- ", 10)

C2D(<zeichen>)
 

Liefert den dezimalen ASCII-Wert eines oder mehrerer Zeichen (Char-TO-Decimal), z.B. n=C2D('A') setzt n auf 65.

C2X(<zeichen>)
 

Liefert den dezimalen ASCII-Wert eines Zeichens (Char-TO-heX), z.B. n= C2X('AB') setzt n auf 4142.

DATE("<format>")
 

Gibt das aktuelle Datum in verschiedenen Formaten zurück (eines von B, D, E, M, N, O, S, U, W), z.B. heute=DATE("S") gibt am 1.2.97 den Text "19970201" zurück.

D2C(<ascii>)
 

Liefert das Zeichen zu einem dezimalen ASCII-Wert (Decimal-To-Character), z.B. SAY D2C(65) gibt den Buchstaben A aus, bzw. cr= D2C(13) weist der Variable CR das Carriage Return Zeichen zu.

FILESPEC(<teil>, <dateiname>)
 

Liefert einen Teil des Dateinamens (aus "Drive", "Path", "Name"), z.B. dir=FILESPEC("Path", ofile)

LEFT(<string>, <num>)
 

Liefert die ersten <num> Zeichen von <string>, z.B. SAY LEFT("BIERFLASCHE", 4) gibt BIER aus.

LENGTH(<string>)
 

Gibt die Anzahl Zeichen des Strings zurück.

LINEIN(<dateiname>)
 

Liest die nächste Textzeile einer Datei aus (siehe Datei-I/O).

LINEOUT(<dateiname>, <text>)
 

Schreibt die nächste Textzeile in eine Datei (siehe Datei-I/O).

POS(<string1>, <string2>)
 

Sucht den ersten String im zweiten String und liefert die Position oder 0, wenn nicht gefunden.

RIGHT(<string>, <num>)
 

Liefert die letzten <num> Zeichen von <string>, z.B. SAY RIGHT("BIERFLASCHE", 7) gibt FLASCHE aus.

STREAM(<dateiname>, …)
 

Führt eine Dateioperation aus (siehe Datei-I/O).

SUBSTR(<string>, <pos>[, <länge>])
 

Liefert <länge> Zeichen ab Position <pos> in <string> zurück. Wird <länge> nicht angegeben, wird der Rest von <string> zurückgeliefert.

STRIP(<string>)
 

Entfernt Leerzeichen am Anfang und Ende einer Zeichenkette, z.B. str= STRIP(str)

TIME("<format>")
 

Gibt die aktuelle Uhrzeit von verschiedenen Formaten (eines von C, H, L, M, N, S) zurück, z.B. SAY TIME("N") zeigt die Uhrzeit in der Form HH:MM:SS.

TRANSLATE(<string>)
 

Setzt alle Zeichen von <string> in Großbuchstaben um.

TRUNC(<n>, <m>)
 

Verkürzt den Wert <n> auf <m> Dezimalstellen.

X2C(<hex>)
 

Liefert das Zeichen zu einem hexadezimalen ASCII-Wert (heX-To-Character), z.B. SAY X2C(41) gibt den Buchstaben A aus, bzw. crlf= X2C(0D0A) weist der Variable CRLF die zwei Zeichen für Carriage-Return/Line-Feed zu.


Datei-I/O
 

Überprüfen, ob eine Datei existiert
 

IF STREAM(<dateiname>, "C", "QUERY EXISTS")\="" THEN …

Zum Schreiben öffnen
 

CALL STREAM <dateiname>, "C", "OPEN WRITE"

Zum Lesen öffnen
 

CALL STREAM <dateiname>, "C", "OPEN READ"

In eine Datei schreiben
 

CALL LINEOUT <dateiname>, <text>

Aus einer Datei lesen
 

<variable>=LINEIN(<dateiname>)

Auf EOF abprüfen
 

IF STREAM(<dateiname>, "S")\="READY" THEN …

Eine Datei schließen
 

CALL STREAM <dateiname>, "C", "CLOSE"


 
/* REXX FILE INPUT EXAMPLE */
    
file= "input.txt"
    
DO FOREVER
    ln= LINEIN(file)
    IF STREAM(file, "S")\="READY" THEN LEAVE
    
    /* process line of file (ln) here */
    
END
CALL STREAM file, "C", "CLOSE"

Die Datei FILEIO.ZRX bei den Beispielen im Rexx Ordner wendet diese Funktionen beispielhaft an.


Übergabe von Parametern an REXX
 

Von der ZOC Kommandozeile bzw. von ZOC-Benutzerknöpfen kann auch ein Parameter an ein REXX Skript übergeben werden, z.B. ZOC "/RUN:script\test.zrx Hello, World"

Solche Parameter können in im REXX Skript mit Hilfe der ARG(1) Funktion abgefragt und ggf. mit PARSE zerlegt werden) (es wird dabei noch dringend empfohlen evtl. führende und nachfolgende Leerzeichen durch STRIP() zu entfernen).
 

/* REXX PARAMETERÜBERGABE */
p= ARG(1)
PARSE VALUE p WITH p1","p2
p1= STRIP(p1)
p2= STRIP(p2)
SAY "Übergebene Parameter: ("||p||") ("||p1||") ("||p2||")"
    

Häufige Funktionen in Visual Basic vs. REXX
 

ASC
 

D2C()

CHR$
 

C2D(), X2C()

CLOSE
 

CALL STREAM(<file>, "C", "CLOSE")

EOF
 

STREAM(<file>, "S")\="READY"

FOR … NEXT
 

DO n=<first> TO <last> … END

INSTR$
 

POS()

MID$
 

SUBSTR()

LEN
 

LENGTH()

OPEN
 

STREAM(<file>, "C", "OPEN …")

INPUT
 

PULL, ZocAsk()

INPUT#
 

LINEIN()

PRINT
 

SAY, ZocWrite, ZocWriteln

PRINT#
 

CALL LINEOUT <file>, …

 

 
← Zurück zu Die Programmierung von ZOC (REXX/DDE)

 

Downloads
Orders
Contact
Support
Terms of Use
Privacy Policy