Wir richten uns ein

E-Books


MS-DOS Kurs


8. Stapelverarbeitung

Der Ihnen vielleicht etwas seltsam anmutende Begriff Stapelverarbeitung stammt noch aus Zeiten, als man wahrhaftig Lochkartenstapel in seinem Rechenzentrum abgab, um dafür (Tage später) eine Druckliste zu erhalten. Damit sich das aber nicht allzu profan anhört, sagte man auch Job dazu. Die PC-Nutzer geben sich modern und sagen Batch, was auch nichts anderes heißt als Stßapel oder Stoß (Papier). Darunter wird eine Folge von Kommandos auf DOS-Ebene verstanden, die ohne Zutun des Nutzers als Block abgearbeitet werden. Ziel ist es, stets wiederkehrende Arbeiten zu automatisieren. Dazu können alle bisher besprochenen Befehle (interne und externe) sowie beliebige Programme verwendet werden. Zusätzlich stellt DOS noch Steuerstrukturen zur Verfühgung, die die eigentliche Kommandosprache ausmachen, um die soll es in diesem Abschnitt gehen. Vom Umfang her ist die DOS-Kommanodsprache recht klein (verglichen mit denen anderer Betriebssysteme), aber sie kann mannigfaltig eingesetzt werden und bildet so ein mächtiges Werkzeug.
Auch ohne weiteres Wissen können wir schon Batch-Dateien schreiben. Und die ganz besondere haben wir schon kennengelernt: AUTOEXEC.BAT. Als nächstes soll eine Batch-Datei angelegt werden, die uns die verfügbaren externen Befehle auf der Festplatte anzeigt. Dazu brauchen wir nun aber einen Texteditor - der COPY-Befehl ist für gröere Arbeiten nicht geeignet. Schreiben Sie also mit dem Editor Ihrer Wahl (Wordstar, Norton-Editor, Turbo-Editor) die neue Datei EXDIR.BAT mit dem Inhalt:
dir\dos*.com/w
Anschließend können Sie die Datei mit ihrem Namen - also EXDIR - aufrufen, und es werden alle COM-Dateien aus dem Verzeichnis DOS (und dort stehen gerade die externen DOS-Befehle) in Kurzform angezeigt. Bei nur einem Befehl in der Kommandodatei ist die Arbeitserleichterung nicht sonderlich groß; wie weitere Befehle verwendet werden können, war schon bei der AUTOEXEC.BAT zu sehen. Was jedoch fehlt, sind Steuerstrukturen für die Wiederholung von Kommandos und zum Prüfen von Bedingungen. Für letzteres gibt es in DOS den IF-Ausdruck. Es können drei verschiedene Arten von Bedingungen getestet werden: die Existenz von Dateien (mit EXIST), die Rückgabe von Fehlernummern durch Programme (ERRORLEVEL) und die Gleichheit von Zeichenketten(==), was besonders für Parameter und Dateinamen verwendet werden kann. Durch den Einsatz von NOT können Aussagen auch jeweils negiert werden. Wenn Sie die Datei CONFIG.SYS listen wollen, aber keine Fehlerausschrift, wenn diese nicht vorhanden ist, dann geht das mit
if exist config.sys type config.sys
Diese Befehlsfolge kann interaktiv eingegeben werden. Im folgenden wird nicht weiter darauf hingewiesen, diese Anweisungen in eine BAT-Datei zu schreiben und zu starten.
Genauso kann auch eine Aktion ausgeführt werden, wenn die Datei nicht vorhanden ist. Oder gleich in beiden Fällen:
if exist config.sys type config.sys
if not exist config.sys
echo CONFIG.SYS ist nicht vorhanden
Die Unterdrückung der Anzeige der Befehle erfolgt mit echo off. Dieser Befehl steht in der Regel in der ersten Zeile einer Stapeldatei - am Ende wird das Echo automatisch wieder eingeschaltet. Noch schöner wäre dieser Batch, wenn er nicht nur auf eine Datei anwendbar wäre, sondern auf beliebige. Dazu geben wir den Dateinamen als Parameter beim Aufruf an. In der Batchdatei steht dafür ein Platzhalter. Die Parameter (bis zu neun Stück) werden mit %1 bis %9 bezeichnet. Der gleiche Batch wie oben für beliebige Dateien sieht so aus:
if exist %1 type %1
if not exist %1 echo %1 ist nicht vorhanden

Der ECHO-Befehl wird - wie bereits gezeigt - entweder dazu benutzt, die Ausgaben der Befehle zu unterdrücken (ON/OFF) oder aber um Meldungen auf den Bildschirm zu bringen. Der Aufruf der angenommenen Datei TEST.BAT erfolgt dann mit
test dateiname
Sie listet als test autoexec.bat entwender die Datei oder schreibt, daß sie nicht vorhanden ist. Als nächstes soll verhindert werden, daß man auch die CONFIG.SYS damit ansehen kann. Alle anderen Dateien ja, aber die Konfiguartionsdatei soll nicht zugänglich sein. Dazu sollte es genügen, das Kommando
if%1==config.sys echo Diese Datei ist tabu
voranzustellen (beachten Sie bitte, daß es sich um zwei Gleichheitszeichen handelt). Beim Aufruf von text config.sys werden Sie feststellen, daß die Ausschrift wirklich kommt, die Datei aber anschließend trotzdem gezeigt wird (sofern sie vorhanden ist). Ursache dafür ist, daß alle Befehle nacheinander durchlaufen werden. Um dem zu begegnen, kann mit GOTO verzweigt werden, indem eine Sprungmarke angegeben wird. Sie kann beliebig lang sein, aber nur 8 Zeichen werden zur Auswertung herangezogen. Die Marke selbst wird von einem Doppelpunkt eingeleitet. Wird sie nicht gefunden, so bricht DOS mit einer Fehlermeldung ab. Das Beispiel von oben sieht dann richtig aus:

echo off
if%1==config.sys goto tabu
if exist %1 type %1
if not exist %1 echo %1 ist nicht vorhanden
exit
:tabu
echo Diese Datei ist tabu.


Beim Dateinamen (wie bei allen Parametern) muß Groß- und Kleinschreibung unterschieden werden.
Als Beispiel für die Übergabe mehrerer Parameter schreiben wir uns jetzt eine Befehlsdatei, die mehrere Dateien listet:
if exist %1 type %1
if exist %2 type %2
if exist %3 type %3

Beim Ausfruf mit
test config.sys autoexec.bat brief.txt
werden alle drei Dateien nacheinander angezeigt. Damit können sie umgehen, daß beim TYPE-Kommando keine Joker erlaubt sind. Trick am Rande: Zum Listen mehrerer Dateien kann auch
copy dateien con
verwendet werden, beispielsweise
copy *.bat con
zum Listen aller BAT-Dateien. Wenn Ihnen das nicht einleuchtet: Einmal aussetzen und zwei Folgen zurück zum COPY-Befehl.
Wie bereits erwähnt, können die Parameter %1 bis %9 verwendet werden (%0 enthält den Namen der BAT-Datei selbst). Sollten Sie wirklich einmal nicht damit auskommen, so kann der SHIFT-Befehl zur Anwendung kommen. Er verschiebt die Parameterkennung nach links. Sie erreichen unter %1 dann den zweiten Parameter und unter %8 den Zehnten. Durch mehrmaliges Anwenden können so alle Parameter zugänglich gemacht werden. Für die meisten Anwendungen wird das aber kaum nötig sein.
Unbefriedigend beim Anzeigen der drei Dateien ist, daß stets genau drei Parameter angegeben werden müssen. Besser wäre es, wenn bei einem weggelassenen Parameter die Aktion nicht ausgeführt wird. Dazu wird die Parameterzeichenkette daraufhin geprüft, ob sie leer ist, und zwar mit
if %1 *==*...
Eine leere Zeichenkette im eigentlichen Sinne ist nicht vorhanden. Deshalb wird ein beliebiges Zeichen angehängt (hier ein Stern) und verglichen, ob es sich nur um einen Stern handelt. Zur besseren Lesbarkeit ist aber auch
if "%1"=="" ...
möglich. Der Batch zum Anzeigen von 1 bis 3 Dateien hat dann folgendes Aussehen:

if exist %1 type %1
if "%2"=="" goto ende
if exist %2 type %2
if "%3"=="" goto ende
if exist %3 type %3
:ende


Wenn Sie genau aufgepaßt haben, werden Sie feststellen, daß jetzt doppelt geprüft wird. Denn ein nicht übergebener Parameter wird als leere Zeichenkette interpretiert und deshalb als Datei nicht gefunden, was auch keine Fehlermeldung auslöst. In vielen Fällen ist es aber wichtig, auf die Existenz eines Parameters zu prüfen. So wurde die Anweisung format %1: beim Fehlen des Laufwerksparameters format; ergeben. Wird die Existenz des Parameters getestet, ergibt sich die Möglichkeit, einen Standard (z.Bsp. a:) anzunehmen.
Nicht unterstützt von der DOS-Kommandosprache werden Tastatureingaben, die dem Nutzer die Auswahl aus inem Menü oder die Beantwortung einer Abfrage (etwa:"Wirklich Formatieren (J/N)") gestatten. Es gibt aber mittels einiger Hilfsprogramme die Möglichkeit dieses Problem zu lösen. Da diese Programme aber nicht zur Grundausstattung gehören wollen wir nur auf einen weiteren Lehrgang (Programmierung von BATCH-Dateien) hinweisen (der demnächst erscheinen wird). Deshalb wollen wir Ihnen einen anderen Trick zeigen, den wir - obwohl häufig in Pupliktionen gezeigt - wegen seiner Nützlichkeit kurz vorstellen möchten. Diesem liegt die Tatsache zugrunde, daß mit ERRORLEVEL der Programmrückkehrcode im Prozessorregister AL ausgewertet wird. Beispielsweise gibt FORMAT (wie den DOS-Unterlagen zu entnehmen ist) eine 0 für fehlerfreie Beendigung der Arbeit, eine 3 für einen Abbruch mit <CTRL><C> bzw. <STRG><C> und eine 4 für einen Diskettenfehler zurück. Das läst sich mit folgendem Batch-Programm ausprobieren:

format a:
if errorlevel 4 goto fehler
if errorlevel 3 goto abbruch
if errorlevel 0 goto okay


usw.
Um Tastatureingaben auszuwerten, wird nur ein kleines Programm benötigt, daß den Tastendruck abfragt und ASCII-Code übergibt. Am einfachsten wird folgendes Assemblerprogramm mit einem Editor erfaßt und durch den Debugger DEBUG (befindet sich unter den externen DOS-Kommandos) geschickt. Das ist auch für den Nutzer mit wenig Erfahrung zu schaffen. Hier das Programm TASTE.ASM:

a
mov ah,0
int 16h
mov ah,4c
int 21h
(Leerzeile)
rcx
8
n taste.com
w
q


Übersetzt wird es durch
debug <test.asm
und das fertige Programm TASTE.COM kann dazu verwendet werden, den Tastencode als ERRORLEVEL zurückzugeben. Es gibt sicher elegantere Lösungen, aber keine kürzere. Sie brauchen nur noch in der ASCII-Tabelle den Zeichencode nachzusehen. Beachten Sie dabei, daß Tasten, die einen erweiterten Code abgeben (Funktionstasten, Komobinationen mit <ALT> oder <CTRL>) keine Verwendung finden können. Das eigentliche Ziel bei der Einführung des ERRORLEVEL war, auf eine fehlerhafte Beendigung eines Programms reagieren zu können. Als Beispiel wird häufig das Assemblieren von Programmen gezeigt und je nachdem, ob das fehlerfrei geschieht oder nicht, wird zum Linken oder zum erneuten Editieren verzweigt.
Wir benutzen den ERRORLEVEL-Ausdruck also wieder einmal zweckentfremdet (wie schon den PROMPT-Befehl). Dazu wird ein kleines Menü erzeugt, aus dem der Anwender ein Programm aussuchen kann, das gestartet werden soll (in diesem Falle Wordstar, dBase, Mulitplan). Die Auswahl erfolgt durch Eingabe des Anfangsbuchstabens (Programm Taste).
Und so könnte eine kleine Batch.Datei aussehen:

echo off
echo Aufruf von Programmen
echo.
echo w - Wordstar
echo m - Multiplan
echo d - dBase
echo.
echo Bitte Auswahl:
taste
if errorlevel 119 goto ws
if errorlevel 109 goto mp
if errorlevel 100 goto db
exit
:ws
c:\text\ws
exit
:mp
c:\clac\mp
exit
:db
c:\data\dbase<7b>

Aus Platzgründen wurde auf jegliche Verschönerungsmaßnahmen verzichtet. Statt des einfachen Programmstarts sollten noch die Standarddirectories eingestellt, Suchpfade festgelegt und eine nette Ausschrift gegeben werden.
Mit echo. wird einfach eine Leerzeile erzeugt. Und nun die Auswertung: if errorlevel 119 testet, ob ein Code größer (!) oder gleich 119 übergeben wurde. Die 119 ist gerade ein kleines w in der ASCII-Tabelle. Dieses w bewirkt dann den Start von Wordstar. Anschließend wird auf m (109) und d (100) geprüft. Wichtig ist die Aussage, daß stets auf größer oder gleich untersucht wird. Das hat den Hintergrund, daß beim Test auf Fehler nicht alle möglichen Code abgefragt werden können. Ein fehlerfreies Programm gibt 0 zurück, und mit aufsteigenden Nummern werden die Fehler schwerwiegender. Auf diese Weise müssen zuerst die schweren Fehler bearbeitet werden, z.Bsp.
if errorlevel 8 goto abbruch
if errorlevel 4 goto warnung
if errorlevel 0 goto okay
So wird bei allen schlimmeren Fällen als 8 abgebrochen, bei Fehler zwischen 4 und 8 gewarnt usw.
Für unser obiges Beispiel heißt das aber, daß bei allen Tasten mit einem Code größer als 119 zu Wordstar verzweigt wird. Also zum Beispiel, wenn Sie ein z eingeben. Und bei einem p gehen sie zu Mulitiplan - ein kleiner Nachteil dieses kurzen Programms. Ein oft begangener Fehler bei dieser Art der Batch-Programmierung ist, daß die Prüfung mit ERRORLEVEL nicht in absteigender Reihenfolge geschieht. Dann landen Sie stets im ersten Menüpunkt.
Wenn Ihnen der Umgang mit dem Programm TASTE zu schwierig erscheint, so können sie auch ASK aus den Norton-Ultilities benutzten. Das oben gezeigte Programm sieht dann (leicht gekürzt) so aus:

echo w - Wordstar
echo m - Mulitplan
echo d - dBase
ask "Bitte Auswahl", dmw
if errorlevel 3 goto ws
if errorlevel 2 goto mp
if errorlevel 1 goto db


usw.
Dem Programm ASK werden neben einer Ausschrift die Anfangsbuchstaben der möglichen Antworten übergeben, und man erhält die Nummer des gedrückten Buchstabens zurück (hier nicht der ASCII-Code). Weiterhin muß aber in absteigender Reihenfolge getestet werden.
Wenn in einem Batch-Programm nur auf einen Tastendruck gewartet werden soll, ohne daß weiter ausgewertet wird, so verwendet man am einfachsten den Befehl Pause:
pause Bitte Diskette in a: einlegen
Die Meldung wird als Kommentar interpretiert und auf dem Bidlschirm ausgegeben, sofern ECHO ON geschaltet ist. DOS fordert mit Weiter -> eine Taste betätigen zur Weiterarbeit auf.
Mit GOTO lassen sich zwar Wiederholschschleifen anlegen, aber die Festlegung von Abbruchbedingungen und die Übergabe anderer Parameter für jeden Umlauf gestalten sich umständlich. Deshalb stellt DOS die FOR-DO-Schleife zur Verfügung. Um beispielsweise alle Pascal-Quelltexte (Erweiterung .PAS) mit dem Turbo-Pascal-Kommandozeilencompiler TPC zu übersetzen, ist folgende Anweisung nötig.
for %%f in (*.pas) do tpc %%f
Solange noch .PAS-Dateien gefunden werden, wird der Aufruf TPC dateiname ausgeführt. Zur Belegung mit dem Dateinamen wird die Variable %%f benutzt. Sie können aber auch jeden anderen Buchstaben mit zwei vorangestellten Prozentzeichen verwenden (im Gegensatz zu Parametern, die aus einem Prozentzeichen und einer Ziffer bestehen). Wird ein FOR-Befehl aber interaktiv eingegeben (also direkt auf der DOS-Kommandoebene und nicht in einer BAT-Datei), so ist nur ein Prozentzeichen zu schreiben.
Des weiteren kann der FOR-Befehl dazu verwendet werden, Aufgaben auszuführen, die allein mit den Jokern nicht gelöst werden können. Zum Beispiel das Anzeigen aller Dateien mit den Erweiterungen .TXT und .DOC in einem Befehl. Hier ist er:
for %%f in (*.txt,*.doc) do type %%f
Oder das Kopieren aller Programmdateien (also Erweiterungen .COM, .EXE und BAT) nach A:
for %%f in (*.com,*.exe,*.bat) do copy %%f
a:%%F

Das Schachteln von Kommandos ist ebenfalls kein Problem. Wenn nur die Dateien auf die Sicherungsdiskette in A. kopiert werden sollen, die dort noch nicht vorhanden sind so geschieht das mit
for %%f in (*.*) do if not exist a:%%f copy %%f
a:

In großen Stapeldateien ist es zweckmäßig, durch Kommentare spätere Änderungen zu erleichtern. Dafür ist REM (Remark) vorgesehen. Kommentarzeilen können an jeder beliebigen Stelle eingefügt werden; sie beeinflussen den Programmverlauf nicht und erscheinen auch nicht auf dem Bildschirm. Beispiel:
rem Batch nach Anregung aus der C't
In Stapeldateien können neben den DOS-Befehlen auch beliebige Programme, also auch andere Stapeldateien, aufgerufen werden. Der Ruf anderer Batch-Dateien hat aber einen unerwünschten Nebeneffekt: Es folgt keine Rückkehr in das rufende Programm. In der gewünschten Weise kann ein Aufruf weiterer Batch-Dateien also nur am Ende (als letzter Befehl) erfolgen. Das hängt mit der internen Organisation der Abarbeitung von Stapeldateien zusammen. Ab DOS-Version 3.30 steht ein neuer Befehl zum Aufruf von Stapeldateien als Unterprogramm zur Verfügung: CALL. Rufen Sie also aus einer BAT-Datei die Datei TEST.BAT mit
call test
auf. Und eine weitere Verbesserung gibt es ab Version 3.30. mit einem vorangestellten @ kann die Ausgabe einer Kommandozeile auf dem Bildschirm unterdrückt werden. Selbst wenn Sie als Erstes echo off stellen erscheint eben dieser Befehl noch auf dem Bildschrim. Schreiben Sie deshalb
@echo off
Auch vor andere Befehle kann ein @ gesetzt werden, das dann jeweils nur für diese Zeile gilt.
Benötigen Sie vor Version 3.30 den CALL-Befehl, so schreiben Sie statt dessen
Command /c test
Damit wird der Kommandointerpreter geladen und die Batch-Datei als Parameter übergeben - allerdings ist mehr Speicherplatz nötig.
Batch-Dateien können stets mit <CTRL><C> (<Strg><C>) unterbrochen werden, auch wenn BREAK OFF eingestellt ist. Dann wird aber nicht der aktuelle Befehl erreicht, sondern erst vor dem nächsten Befehl die Ausschrift
Stapeldatei abbrechen (J/N)
ausgegeben. Und weil wir gerade beim Abbrechen sind: Gerade in Batch-Dateien kann es schnell zu Laufwerksfehlern kommen, zumeist, weil keine (formatierte) Diskette im Laufwerk liegt. Man erhält die Ausschrift
Fehler beim Schreiben in Laufwerk A
Abbrechen, Wiederholen, Fehler

Die Eingabe des Anfangsbuchstabens genügt. Was unterscheidet diese Möglichkeiten ? Mit A für Abbrechen wird der aktuelle Befehl beendet. In den meisten Fällen ist dieser Variante der Vorzug zu geben, weil sie keinen Schaden anrichtet. Interessante Möglichkeiten werden mit F für Fehler geboten. Hier wird die Fehlernummer an das rufende Programm (in diesem Falle die Batch-Datei) übergeben. Dort können sie wie oben beschrieben mit ERRORLEVEL getestet und entsprechende Maßnahmen eingeleitet werden. Viel ist damit im Falle eines Laufwerksfehlers nicht erreicht, aber es könnte zum Beispiel eine detailierte Fehlermeldung gebracht werden. Wiederholen (w) kann zum Beispiel verwendet werden, wenn die Diskette mit einem Schreinschutz versehen war und nach dem Entfernen weiter gearbeitet werden soll. Aber Vorsicht: Gefährlich kann es sein, die Diskette zu wechseln und dann W zu drücken. In diesem Falle können im Speicher befindliche Informationen der alten Diskette (Directory) geschrieben und die Informationen der neuen Diskette zerstört werden.
Beachten Sie bitte, daß Batch-Dateien nicht den Namen bereits vorhandener Befehle (z.Bsp. DIR.BAT) erhalten dürfen. Bei Eingabe eines Kommandos prüft DOS zuerst, ob es sich um einen internen (und damit reservierten) Befehl handelt. In diesem Falle wird dieser aufgerufen. Auch wenn der Name eines externen Befehls oder eines beliebigen Programms genutzt wird, kommt die BAT-Datei nicht zum Zuge. DOS sucht stets zuerst nach einer COM-Datei, dann nach einer EXE-Datei und erst ganz zum Schluß nach einer eventuellen BAT-Datei.
Da Sie nun schon erfahrene DOS-Programmierer sind zum Schluß noch ein Trick zum Nachdenken. Wenn Sie einmal Zeit und Datum einer Datei ändern wollen, so ist das recht müßig. Sie müßte in einem Editor geladen und wieder gespeichert werden, damit DOS automatisch die neue Zeit setzt. Und was machen Sie mit einer Datei, die nicht aus Text besteht ? Mit dem Befehl
copy /b datei +,,
setzten Sie Datum und Zeit einer oder mehrerer Dateien auf den aktuellen Stand. Der Schalter /b ist für eben diese Nicht-Textdateien zuständig, die sonst erheblich zusammengekürzt werden, weil das Dateiende falsch interpretiert wird. Probieren Sie es doch einmal. Ein bißchen mehr über die Batch-Programmierung können Sie in unserem Lehrmaterial "Batch-Programmierung" (was demnächst erscheinen soll) lesen.


(c) Jürgen Richter