Tech-Ecke / DOS Inhalt / Batch-"Programmierung"

 

Batch-"Programmierung" (Batchdatei/Stapelverarbeitungsdateien)

Einige der hier aufgeführten Befehl bzw. Script-Schnipsel sind nur in der Konsole (CMD ) unter Windows lauffähig und somit in der Rubrik DOS eigentlich falsch platziert. Jedoch möchte ich für Diese keine eigene Rubrik eröffnen und habe sie stattdessen mit einem Windows Logo versehen. Entsprechend klebt an reine DOS Scipts einDOS Logo .

Diese Seite beinhaltet:


Anwendung starten ohne zu Warten

Möchte man zwei Anwendungen "gleichzeitig" über eine Batchdatei starten so muss man die Anwendungen mit dem Befehl Start ausführen. Ansonsten startet die Batchdatei zunächst nur die eine Anwendung und wartet bis diese beendet ist bevor die nächste gestartet wird.

  Start "C:\Windows\notepad.exe"
Start "C:\Windows\regedit.exe"
 


 
Ausgabe / Textausgabe

Ausgabe der Befehlsanweisung unterdrücken

  @dir   REM das vorangestellte @ unterdrückt die Ausgabe der Befehlsanweisung für diesen Befehl

@echo off   REM alle Ausgabe ab jetzt unterdrücken
echo.   REM Leerzeile
echo Hallo Welt
@echo on   REM Ausgabe wieder einschalten
 

Bildschirm löschen

  cls
 

Schriftfarbe und Hintergrund ändern

Color [HintergrundSchriftfarbe] - Es stehen folgende 16 Farben von 1 - F zur Verfügung:

0 Schwarz 1 Dunkelblau 2 Dunkelgrün 3 Blaugrün
4 Dunkelrot 5 Lila 6 Ocker 7 Hellgrau
8 Dunkelgrau 9 Blau A Grün B Zyan
C Rot D Magenta E Gelb F Weiß
               
  color 0A   REM Hintergrund schwarz, Schrift grün
 



  Verwenden von Variable

Einer Variable kann beim Deklarieren über den Befehl "Set" gleich ein Wert zugewiesen werden. 

  @echo off
set
Vari=Test

type Ordner\%Vari%.txt
 

Prüfen ob Variable existiert

  @echo off
if defined s (echo variable s existiert) else (echo variable s existiert nicht)
 



 
String Operationen

Zeichen in Stringvariable ersetzen

Ersetze "A" durch "B". Das Ergebnis bzw. die Ausgabe wird "TestB" sein.

  @echo off
set
Vari=TestA
set Vari=%Vari:A=B%
echo %Vari%
 

Einer Stringvariable Zeichen anhängen

Füge zu "Te"  "st" hinzu. Das Ergebnis bzw. die Ausgabe wird "Test" sein.

  @echo off
set
Vari=Te
set Vari=%Vari%st
echo %Vari%
 

Stringvariable beschneiden

Die letzten 3 Zeichen abschneiden

  @echo off
set
Vari=Test.txt
set Vari=%Vari:~0,-3%
echo %Vari%
 

Nach den ersten 4 Zeichen abschneiden

  @echo off
set
Vari=Test.txt
set Vari=%Vari:~0,4%
echo %Vari%
 

Nach den ersten 2 Zeichen, 4 Zeichen ausschneiden

  @echo off
set
Vari=Test.txt
set Vari=%Vari:~2,4%
echo %Vari%
 



  If Then Else - Verzweigungen

  @echo off
set s=Otto
if %s%==Otto echo ja ich bin Otto
if %s%==Udo (echo ich bin Otto) else (echo ich bin nicht Otto)

if defined v (echo Variable v ist definiert) else (echo Variable v ist nicht definiert)
if [%v%] == [] echo Variable v ist leer oder nicht definiert

if exist Test.txt (echo Datei existiert) else (echo Datei existiert nicht)
 

 



 
Countdown Zähler (Sekunden)

Wartet 30 Sekunden bevor es weiter geht.

 
 



  Datei- und Verzeichnisoperationen


Datei/Ordner vorhanden

  @echo off
if exist Test.txt (echo Datei existiert) else (echo Datei existiert nicht)
if exist C:\Windows (echo Ordner existiert) else (echo Ordner existiert nicht)
 

Datei/Ordner umbenennen

  ren C:\Test.txt C:\Test.txt  REM absolute Pfadangabe

ren Test.txt Neu.txt  REM relative Pfadangabe
 

Aktuelles Verzeichnis ermitteln

  @echo %0 liegt in %~dp0
 

Datei/Ordner umbenennen

  ren C:\Test.txt C:\Test.txt  REM absolute Pfadangabe

ren Test.txt Neu.txt  REM relative Pfadangabe
 

Datei kopieren (Zielordner muss vorhanden sein Ordner )

  copy C:\Test.txt C:\Ordner\Test.txt  REM absolute Pfadangabe

copy Test.txt Ordner\Test.txt  REM relative Pfadangabe

copy C:\Test.txt C:\Ordner\Neu.txt  REM Kopieren mit gleichzeitigem Umbenennen
 

Datei verschieben (Zielordner muss vorhanden sein Ordner )

  move C:\Test.txt C:\Ordner\Test.txt

move C:\Test.txt C:\Ordner\Neu.txt  REM Kopieren mit gleichzeitigem Umbenennen
 

Datei löschen

  del C:\Test.txt
 

Ordner erstellen

  md C:\Ordner
 

Ordner löschen (nur bei leeren Ordner möglich)

  rd C:\Ordner
 

löschen von Ordnern inkl. Inhalt

  deltree C:\Ordner REM "/y" = ohne nachzufragen

rd C:\Ordner /s REM so gehts auch unter Windows, "/q" = ohne Nachfrage
 


In Ordner navigieren - relative Pfadangabe

  REM rückwärts gerichtet - springe zuerst einen Ordner zurück
type ..\test.txt

REM oder

REM vorwärts gerichtet  - springe zuerst in den Ordner
type Ordner\test.txt

 


Aktueller Dateipfad ermitteln

  @echo off

REM Variante 1
for /f "tokens=2,*" %%i in ('dir /a:d ') do if "%%i"=="von" set "Pfad=%%j"
echo %Pfad%

REM Variante 2
echo %CD%

REM Variante 3
echo %~dp0%
 


Lokaler Ordner als Laufwerk mappen

  subst L: "C:\Test"

REM Erstellt ein Laufwerl mit dem Buchstaben L mit dem Inhalt vom Ordner C:\Test
 



  Robocopy

Robocopy ist ein kleines aber mächtiges Kopierprogramm für die Windowskonsole und gehört sein Windows Vista zu den Bordmitteln. Hier soll nur mal das Synchronisieren (Spiegeln) zweier Ordner und der Ansatz eines Inkremental-Backups gezeigt werden.

Beipsiel #1) Spiegeln zweier Ordner:

Der Schalter "/mir" veranlasst eine Spieglung eines Quell-Ordners zu einem Ziel-Ordner, inklusive aller Unterverzeichnisse. Der Schalter "/dst" verhindert das komplette Kopieren aller Dateien nach einer Sommer/Winterzeit Umstellung. Das Ergebnis ist, ungeachtet des aktuellen Inhalts des Zielordners immer eine 1:1 Kopie vom Quell-Ordner. Gelöschte Dateien im Quell-Ordner werden also auch im Ziel-Ordner gelöscht!    

  robocopy /mir /dst "C:\QuellOrdner" "C:\ZielOrdner"
 

Beispiel #2) Inkrementalbackup:

Der Schalter "/m" veranlasst Robocopy nur Dateien zu kopieren die das Archivattribut "A" besitzen und nimmt dieses dann nach dem erfolgten Kopieren der Quelle weg. Im Gegensatz zum Schalter "/mir" wird im Ziel-Ordner nichts gelöscht, jedoch überschrieben wenn bereits vorhanden. Der Schalter "/s" lässt Robocopy auch alle Unterverzeichnisse verarbeiten. Das Archiv-Attribut (A) wird jeder neuen, geänderten oder verschobenen Datei zugewiesen und lässt sich über "Eigenschaften/Details" anzeigen. Der Kopiervorgang wird zunächst wie folgt gestartet:  

  robocopy /m /s "C:\QuellOrdner" "C:\ZielOrdner"
 

Um daraus nun ein echtes Inkrementalbackup zu basteln, muss aber noch das Überschreiben von vorhandenen Dateien verhindert werden. Das gelingt indem man für jeden Kopiervorgang ein eigenes Unter-Verzeichnis im Ziel-Ordner anlegt. Hier bietet sich das aktuelle Datum + Uhrzeit an - siehe auch hier. Das Ganze könnte dann so aussehen:

  REM Zwischensicherung
set
Vari=%date:~-4%-%date:~-7,2%-%date:~-10,2%@%time:~-11,2%-%time:~-8,2%-%time:~-5,2%
robocopy /m /s
"C:\QuellOrdner" "C:\ZielOrdner\%Vari%"
 

Zu Jedem Inkrementalbackup gehört auch eine Full-Backup auf dem die Inkremente aufbauen. Beim aller ersten Kopiervorgang sollte das auch so geschehen, da alle Dateien (hoffentlich) ein Archiv-Attribut besitzen. Um hier auf der sicheren Seite zu sein, sollte man zuvor alle Dateien des Quellverzeichnisses ein Archiv-Attribut zukommen lassen, das geht so:

  REM Vollsicherung
attrib +A
"C:\QuellOrdne\*.*" /s
set
Vari=%date:~-4%-%date:~-7,2%-%date:~-10,2%@%time:~-11,2%-%time:~-8,2%-%time:~-5,2%
robocopy /m /s
"C:\QuellOrdner" "C:\ZielOrdner\%Vari%_Full"
 

Ein weiteres Full-Backup wird dann genau auf diesem Wege angestoßen. Der Schalter "/s" veranlasst Attrib auch alle Unterverzeichnisse zu durchlaufen.


Beispiel #3) Differentialbackup:

Vollständigkeithalber hier noch ein Beispiel eines Differentialbackups. Hier kommt der Schalter "/a", statt "/m" zum Einsatz. Dieser verhält sich zunächst gleich wie der Schalter "/m", nimmt aber nach dem Kopieren das Archivattribut der Quelldatei nicht weg. Das bedeutet, dass bei jeder Sicherung immer alle, gegenüber dem letzten Full-Backup geänderte Dateien kopiert werden.
Aber: Das erste und alle weiteren Full-Backups werden auch hier mit dem Schalter "/m" erledigt! Danach folgen die Zwischenbackups mit Schalter "/a" statt "/m".  

  REM Vollsicherung
attrib +A
"C:\QuellOrdne\*.*" /s
set
Vari=%date:~-4%-%date:~-7,2%-%date:~-10,2%@%time:~-11,2%-%time:~-8,2%-%time:~-5,2%
robocopy /m /s
"C:\QuellOrdner" "C:\ZielOrdner\%Vari%_Full"
 
  REM Zwischensicherung
set
Vari=%date:~-4%-%date:~-7,2%-%date:~-10,2%@%time:~-11,2%-%time:~-8,2%-%time:~-5,2%
robocopy /a /s
"C:\QuellOrdner" "C:\ZielOrdner\%Vari%"
 

Zum Ausführen eines weiteren Full-Backups wird wie beim Inkrementalbackup das Archivattribut mittels "attrib -A..." für alle Quelldateien gesetzt und Robocopy mit dem Schalter "/m" gestartet.

Das hier Vorgestellte kratzt nur an der Oberfläche von den Möglichkeiten die Robocopy bietet. Durch Eingabe von "robocopy /?" erhält man eine Übersicht alle Optionen. Wobei auch ganz klar gesagt sein muss, dass die Stärken von Robocopy im Spiegeln von Verzeichnissen liegt und das erstellen von Inkremental- und Differenzialbackups einige Knackpunkte hat. Beispielsweise wird das Umbenennen oder verschieben von Ordnern über den Schalter "/m" und "/a" nicht erkannt, was das Wiederherstellen schnell zum Alptraum werden lässt. Nutzt man das Backup jedoch lediglich um einzelne, versehendlich gelöschte oder überschriebene Dateien wieder herstellen zu können, so kann man sich damit arrangieren.



  + Alle Dateien in einem Verzeichnis einzeln zippen (packen) mit 7z

Mit dieser Batchanweisung werden alle Dateien eines Verzeichnises in separate Zip-Archive gepackt. Dabei wird vorausgesetzt, dass 7z im Standard-Installationsverzeichnis installiert wurde, ansonsten "C:\Programme\7-Zip\7z.exe" entsprechend bitte anpassen.

  for %%X in (*.*) do "C:\Programme\7-Zip\7z.exe" a -t7z -aoa "%%X.7z" "%%X"
 

Möchte man nur einen bestimmten Dateityp behandeln, so ersetzt man (*.*) durch z.B. (*.bmp).
Durch das Ändern in (*) werden statt alle Dateien alle Ordner einzeln gepackt.
Das Attribut -aoa veranlasst das Überschreiben eines eventuell vorhandenen Archivs mit gleichem Namen.

Ohne ursprüngliche Endung

Bei der oben gezeigten Methode bleibt die ursprüngliche Endung erhalten. Die Datei "Test.txt" wird somit zur "Test.txt.7z". Der folgende Code verhindert dies, hat aber auch den Nachteil, dass ein eventuell vorhandener "." (Punkt) im Dateinamen das Script stolpern lässt.

  @echo off
REM der Variable die passende Endung zuweisen - Beispiel: txt
set e=txt
for /f "tokens=1,2 delims=." %%X in ('dir *%e% /b') do (
echo packe: %%X.%%Y
"C:\Program Files\7-Zip\7z.exe" a "%%X.zip" "%%X.%%Y" >NUL
)
pause
 



 
Neuer Ordner erstellen mit Datum und Uhrzeit

Zuerst wird der Ordnername, bestehend aus Datum + Uhrzeit in die Variable Vari geschrieben. Hierzu wird der Rückgabewert von date und time entsprechend zurechtgeschnibbelt. Der Ordnername sie dann wie folgt aus: "2015-12-20--23-07-22" und wurde am 20 Dezember 2015, 22 Sekunden nach 23:07 Uhr erzeugt. 

  set Vari=%date:~-4%-%date:~-7,2%-%date:~-10,2%---%time:~-11,2%-%time:~-8,2%-%time:~-5,2%
mkdir %Vari%
 



  Alle Dateinamen eines Dateityps als String auslesen

Alle Textdatein im aktuellen Verzeichnis auslesen.

  @Echo Off
for %%p in (*.txt) do echo %%p
 



 
Auswahlmenü unter Windows

  @Echo Off

:MENUE
cls
echo Bitte waehlen:
echo --------------
echo 1: Option 1
echo 2: Option 2
echo 3: Option 3
echo 4: Nix
echo --------------
echo.

set x=
set /p x="Bitte Zahl eingeben: "

if '%x%' == '1' goto OPT1
if '%x%' == '2' goto OPT2
if '%x%' == '3' goto OPT3
if '%x%' == '4' goto ENDE

echo Bitte eine Zahl von 1-4 waehlen
goto :MENUE

:OPT1
echo Option 1 wurde gewaehlt
goto :ENDE

:OPT2
echo Option 2 wurde gewaehlt
goto :ENDE

:OPT3
echo Option 3 wurde gewaehlt
goto :ENDE

:ENDE
Pause
 



 
Auswahlmenü unter DOS

Diese Batch benötigt die Befehlsdatei "CHOICE.COM", welche sich im DOS-Verzeichnis von MS-DOS 6.x befindet.

  @Echo Off

cls
echo Bitte waehlen:
echo --------------
echo 1: Option 1
echo 2: Option 2
echo 3: Option 3
echo 4: Nix
echo --------------
echo.

choice /n /c:1234 "Bitte Auswahl eingeben: "

if errorlevel 4 goto ENDE
if errorlevel 3 goto OPT3
if errorlevel 2 goto OPT2
if errorlevel 1 goto OPT1

:OPT1
echo Option 1 wurde gewaehlt
goto :ENDE

:OPT2
echo Option 2 wurde gewaehlt
goto :ENDE

:OPT3
echo Option 3 wurde gewaehlt
goto :ENDE

:ENDE
Pause
 




 
Reboot ausführen

DOS selbst bietet keinen Befehl dafür, aber man kann sich hier selbst einen Dateibefehl basteln. Dazu folgenden Code in einem Texteditor schreiben und als reboot.scr abspeichern.

  N REBOOT.COM
A 100
MOV AX,0040
MOV DX,AX
MOV AX,1234
MOV [0072],AX
JMP F000:FFF0

RCX
10
W
Q

Zum kompilieren benötigt man die Befehlsanwendung  DEBUG.EXE, welche Bestanteil eines DOS ist und sich im Systemverzeichnis befindet. Bei Win9x ist debug.exe im Ordner (C:\Windows\Command) zu finden.
Dann im DOS-Prompt folgende Befehl, imVerzeichnis der SCR-Datei absetzen:

  debug < reset.scr

Nun sollte sich der neue Befehl "REBOOT.COM" erstellt haben. Durch einfaches Ausführen sollte sich damit der Rechner neu Starten lassen. Ich stelle hier mal die reboot.scr und eine, unter DOS7.1 kompilierte reboot.com zum herunterladen bereit.

  DOS-Reboot.zip

 

Die Option Drucken funktioniert erst ab Netscape V4.0 bzw. I-Explorer 5.0 !

[letzte Aktualisierung 20.12.2015]