Batch - ein paar Basics die man kennen sollte
Hallo Batchfreunde,
in den letzten Tagen habe ich ein paar Dinge über Batch gelernt, die eigentlich zu den Basics gehören, mir aber bisher unbekannt waren, obwohl ich relativ viel mit Batch mache und das schon seit MS-Dos 5.0.
Für den Fall, dass diese Dinge dem einen oder anderen unter Euch auch noch unbekannt sein sollten, habe ich es hier zusammengefasst.
Alles Folgende ist von mir nur reproduktiv, aus diversen Quellen zusammengestellt und mit eigenen Worten kommentiert.
Anmerkungen und Korrekturen aus den Kommentaren, habe ich in diesen Beitrag einpflegt, damit er möglichst korrekt und vollständig ist.
Inhalt
1.
2.
3.
3.
4.
Wer mit diesen Befehlen vertraut ist, kann sich das Weiterlesen sparen.
1. Zufalls-Zahl
Es steht eine Umgebungsvariable zur Verfügung, die einen Zufallswert liefert.
Diese heißt
%random%
Wertebereich 0-32767
Quelle: https://ss64.com/nt/syntax-random.html
Wichtig:
Mit set /a können nur Integeroperationen ausgeführt werden.
Es wird daher an jeder Stelle einer Formel ausschließlich mit Ganzzahlen gerechnet. Eventuelle Nachkommastellen werden sofort verworfen, was gleichbedeutent wäre mit genereller Abrundung auf ganze Zahlen und nicht nur im Endergebnis, sondern schon bei jedem Teilschritt.
Betrachten wir die funktionierende Formel mit dem Maximalwert von Random (32767) in Teilschritten:
Formel: (32767*6/32768)+1
1.) 32767 * 6 = 196602
2.) 196602 / 32768 = 5,9998169 => 5
3.) 5 + 1 = 6
Sähe die Formel wie folgt aus, was zunächst gleichwertig erscheint, würde sie nicht wie gewünscht funktionieren.
Formel: (32767/32768)*6+1
1.) 32767/32768 = 0,9999695 => 0
2.) 0 * 6 = 0
3.) 0 + 1 = 1
Diese Formel würde immer 1 als Ergebnis haben, egal welchen Wert wir von Random erhielten.
2. Ausgaben umleiten
Wenn ich eine Ausgabe in eine Datei umleitet, dann lasse ich das Leerzeichen vor dem Umleitungszeichen normalerweise weg.
Beim Rumprobieren mit
Versucht man eine Ausgabe, die mit einer freistehenden Ziffer endet, in eine Datei umzuleiten, klappt das nicht so wie gewohnt.
Der Grund ist, dass die Funktion des Umleitungszeichens durch eine führende Ziffer geändert wird.
Zusätzlich wurde ich gewahr, dass Ausgaben unterschiedlicher Art sein können und zwar "Meldungen" und "Fehlermeldungen".
Standardmäßig werden beide Arten in der Console ausgegeben, wobei sich beide Arten getrennt umleiten lassen.
0 steht für stdin (Standard In) und 3-9 sind undefiniert.
Was bedeutet das und wie kann man das nutzen?
Ein paar Beispiele für
ist gleichbedeutend mit
Um beide Arten umzuleiten kann man sie in getrennte Dateien umleiten
Um beide Arten in dieselbe Datei umzuleiten muss man stderr zu stdout oder stdout zu stderr umleiten und die "Summe" in eine Datei
Statt in eine Datei umzuleiten kann man auch ins Nirwana umleiten (das Null-Device) =
Man kann auch explizit zur Console =
Nehmen wir mal eine Batch als Beispiel:
Wir rufen die Batch auf und leiten deren Ausgaben nach
Auch wenn wir die Batch so aufrufen ist die explizite Umleitung zu
Eine Anmerkung:
Alle Beispiele hab ich mit einfachem Umleitungszeichen aufgezeigt. Sie funktionieren aber auch mit doppeltem Umleitungszeichen.
Ganz allgemein lassen sich Umleitungen unterschiedlich positionieren.
Alle drei dargestellten Varianten erzeugen dieselbe Ausgabe.
@rubberman empfiehlt grundsätzlich die Umleitung an den Anfang zu setzen.
Das helfe nicht nur das Deuten von Ziffern als Streamnummer zu vermeiden, sondern trage auch wesentlich zur Lesbarkeit des Codes bei.
Sein Beispiel:
im Vergleich zu
In diesem Beispiel ist der zweite Code besser lesbar.
@rubberman merkte noch an, dass es auch noch
Umleitung aus einer Datei:
3. Ausgaben von Ziffern umleiten
Nur bei #=1 landet
Bei allen anderen Ziffern landet
Um die besondere Funktion von
Möchte man das Leerzeichen vermeiden, so gibt es diese Alternativen:
a)
b)
c)
d)
e)
fa)
fb)
Am eingängigsten finde ich b), da es bei anderen Dingen genauso funktioniert und mir entsprechend vertraut ist.
Kommentar zu c)
Von der Verwendung von
Aus Performancegründen ist
Es hat aber auch noch Sicherheitsaspekte.
In dem Fall würde keine Ausgabe erfolgen, sondern diese
Im Falle von
Wie auch immer, der Punkt hinter
Es gibt dazu mehrere Alternativen und zu deren Risiken und Nebenwirkungen kann hier nachgelsen werden:
http://www.dostips.com/forum/viewtopic.php?t=774 und http://www.dostips.com/forum/viewtopic.php?t=1900
Die zu bevorzugenden Alternative ist die öffnende Klammer, also
Diese hat die wenigsten Nebenwirkungen. Der Kommandozeileninterpreter wertet sie nicht als öffnende Klammer in Klammerausdrücken eines Codes.
Interessant ist das bei der Ausgabe von Zeilen, die nur aus Leerzeichen und/oder Tabs bestehen.
Ebenso interessant ist das bei der Ausgabe von Variablen die eventuell leer (nicht definiert) sind.
Hier die resultierenden Ausgaben:
Nebenbei erwähnt:
4. Zum Schluss das Ende
Eine Batchdatei endet, wenn sie ihre letzte Zeile abgearbeitet hat oder vorzeitig beendet oder verlassen wird.
Eine schlechte Möglichkeit zum vorzeitigen Beenden ist der Befehl
Schlecht insofern, dass er nicht nur die Batch beendet, sondern auch die Eingabeaufforderung schließt, aus der man heraus die Batch gestartet hat.
Ruft man eine Batchdatei per
Schreibt man statt
a.cmd
b.cmd
Will man
Anmerkung: In den Beispielen
Eine weitere, gute Möglichkeit zum vorzeitigen Beenden ist der Befehl
Ein Beispiel für ein vorzeitiges Beenden ist das hier:
Anmerkungen:
%random% liefert bei jedem Aufruf ein neues Zufallsergebnis.
Die Umleitungszeichen
Ergänzend und optional kann man bei
Gruß /b 0
Frank
PS: Danke für die konstruktiven Kommentare
in den letzten Tagen habe ich ein paar Dinge über Batch gelernt, die eigentlich zu den Basics gehören, mir aber bisher unbekannt waren, obwohl ich relativ viel mit Batch mache und das schon seit MS-Dos 5.0.
Für den Fall, dass diese Dinge dem einen oder anderen unter Euch auch noch unbekannt sein sollten, habe ich es hier zusammengefasst.
Alles Folgende ist von mir nur reproduktiv, aus diversen Quellen zusammengestellt und mit eigenen Worten kommentiert.
Anmerkungen und Korrekturen aus den Kommentaren, habe ich in diesen Beitrag einpflegt, damit er möglichst korrekt und vollständig ist.
Inhalt
1.
echo %random%
2.
xcopy leer 2> datei.txt 1>&2
("xcopy leer" ist hierbei nur ein Befehl, der zu einem Fehler führt)3.
echo ^1> datei.txt
3.
echo.Text
und echo(Text
4.
exit /b %wert%
Wer mit diesen Befehlen vertraut ist, kann sich das Weiterlesen sparen.
1. Zufalls-Zahl
Es steht eine Umgebungsvariable zur Verfügung, die einen Zufallswert liefert.
Diese heißt
%random%
Wertebereich 0-32767
set /a schulnote=(%RANDOM%*6/32768)+1
echo %schulnote%
*6
sorgt in dieser Formel dafür, dass der Wertebereich für %schulnote%
1-6 ist.Quelle: https://ss64.com/nt/syntax-random.html
Wichtig:
Mit set /a können nur Integeroperationen ausgeführt werden.
Es wird daher an jeder Stelle einer Formel ausschließlich mit Ganzzahlen gerechnet. Eventuelle Nachkommastellen werden sofort verworfen, was gleichbedeutent wäre mit genereller Abrundung auf ganze Zahlen und nicht nur im Endergebnis, sondern schon bei jedem Teilschritt.
Betrachten wir die funktionierende Formel mit dem Maximalwert von Random (32767) in Teilschritten:
Formel: (32767*6/32768)+1
1.) 32767 * 6 = 196602
2.) 196602 / 32768 = 5,9998169 => 5
3.) 5 + 1 = 6
Sähe die Formel wie folgt aus, was zunächst gleichwertig erscheint, würde sie nicht wie gewünscht funktionieren.
Formel: (32767/32768)*6+1
1.) 32767/32768 = 0,9999695 => 0
2.) 0 * 6 = 0
3.) 0 + 1 = 1
Diese Formel würde immer 1 als Ergebnis haben, egal welchen Wert wir von Random erhielten.
2. Ausgaben umleiten
Wenn ich eine Ausgabe in eine Datei umleitet, dann lasse ich das Leerzeichen vor dem Umleitungszeichen normalerweise weg.
echo Text > datei.txt
(schreibt "Text " (mit dem Leerzeichen) in die Datei)echo Text> datei.txt
(schreibt "Text" (ohne das Leerzeichen) in die Datei)Beim Rumprobieren mit
%random%
stieß ich auf eine Merkwürdigkeit, deren Untersuchung mich zu der Erkenntnis brachte, dass Ausgabe-Umleitungen komplexer sein können, als mir bisher bekannt war.Versucht man eine Ausgabe, die mit einer freistehenden Ziffer endet, in eine Datei umzuleiten, klappt das nicht so wie gewohnt.
Der Grund ist, dass die Funktion des Umleitungszeichens durch eine führende Ziffer geändert wird.
Zusätzlich wurde ich gewahr, dass Ausgaben unterschiedlicher Art sein können und zwar "Meldungen" und "Fehlermeldungen".
Standardmäßig werden beide Arten in der Console ausgegeben, wobei sich beide Arten getrennt umleiten lassen.
" 1> "
- leitet nur stdout (Standard Out) um, also nur Meldungen" 2> "
- leitet nur stderr (Standard Error) um, also nur Fehlermeldungen" > "
- ist ein Synonym für " 1> "
0 steht für stdin (Standard In) und 3-9 sind undefiniert.
Was bedeutet das und wie kann man das nutzen?
Ein paar Beispiele für
Eingaben
und deren Ausgaben
:xcopy leer
Datei leer nicht gefunden
(das ist eine Fehlermeldung)0 Datei(en) kopiert
(das ist nur eine Meldung/Information)xcopy leer > datei.txt
ist gleichbedeutend mit
xcopy leer 1> datei.txt
(es werden nur die Meldungen umgeleitet)Datei leer nicht gefunden
(landet in der Console)0 Datei(en) kopiert
(landet in der Datei)xcopy leer 2> datei.txt
(es werden nur die Fehlermeldungen umgeleitet)Datei leer nicht gefunden
(landet in der Datei)0 Datei(en) kopiert
(landet in der Console)Um beide Arten umzuleiten kann man sie in getrennte Dateien umleiten
xcopy leer 1> meldung.txt 2> fehler.txt
(es werden alle Ausgaben umgeleitet)Datei leer nicht gefunden
(landet in der Datei "fehler.txt")0 Datei(en) kopiert
(landet in der Datei "meldung.txt")Um beide Arten in dieselbe Datei umzuleiten muss man stderr zu stdout oder stdout zu stderr umleiten und die "Summe" in eine Datei
xcopy leer 1> datei.txt 2>&1
(es wird 2 nach 1 umgeleitet und 1+2 in die Datei)xcopy leer 2> datei.txt 1>&2
(es wird 1 nach 2 umgeleitet und 1+2 in die Datei)Datei leer nicht gefunden
(die Fehlermeldung landet in der Datei)0 Datei(en) kopiert
(die Meldung landet in der Datei)Statt in eine Datei umzuleiten kann man auch ins Nirwana umleiten (das Null-Device) =
nul
Man kann auch explizit zur Console =
con
umleiten, was zunächst sinnlos erscheint, da die Console ja normalerweise ohnehin das Ausgabeziel ist.Nehmen wir mal eine Batch als Beispiel:
@echo off
echo Hallo
xcopy leer
REM Fehler : Datei leer nicht gefunden
REM Meldung: 0 Datei(en) kopiert
echo Welt> con
nul
umbatch.cmd > nul
Hallo
(landet wie erwartet im Nichts, nul
)Datei leer nicht gefunden
(landet als Fehlermeldung in der Console, da nur "1" umgeleitet ist und nicht "2")0 Datei(en) kopiert
(landet als Meldung im Nichts, nul
)Welt
(wird in der Console ausgegeben)Auch wenn wir die Batch so aufrufen ist die explizite Umleitung zu
con
davon unbetroffenbatch.cmd > nul 2>&1
Welt
(wird in der Console ausgegeben, der Rest landet bei nul
)Eine Anmerkung:
Alle Beispiele hab ich mit einfachem Umleitungszeichen aufgezeigt. Sie funktionieren aber auch mit doppeltem Umleitungszeichen.
" 1> datei.txt"
leitet in "datei.txt" um und erzeugt die Datei dabei neu." 1>> datei.txt"
leitet in "datei.txt" um und hängt die Ausgabe an den vorhandenen Dateiinhalt an.Ganz allgemein lassen sich Umleitungen unterschiedlich positionieren.
>"test.txt" echo Hallo
- Umleitung am Anfangecho> "test.txt" Hallo
- Umleitung mittendrinecho Hallo> "test.txt"
- Umleitung am EndeAlle drei dargestellten Varianten erzeugen dieselbe Ausgabe.
@rubberman empfiehlt grundsätzlich die Umleitung an den Anfang zu setzen.
Das helfe nicht nur das Deuten von Ziffern als Streamnummer zu vermeiden, sondern trage auch wesentlich zur Lesbarkeit des Codes bei.
Sein Beispiel:
echo Hallo!>"test.txt"
echo Das ist eine Testzeile>>"test.txt"
echo und noch eine.>>"test.txt"
>"test.txt" echo Hallo!
>>"test.txt" echo Das ist eine Testzeile
>>"test.txt" echo und noch eine.
@rubberman merkte noch an, dass es auch noch
<
gäbe (Umleitung zum stdin).Umleitung aus einer Datei:
@echo off
echo Hallo Welt> datei.txt
set /p meineVar= < datei.txt
del datei.txt
echo %meineVar%
Hallo Welt
wird in datei.txt
geleitet.set /p meineVar=
belegt die Variable meineVar
mit was auch immer man anschließend in der Eingabeaufforderung eintippt und mit [Enter] abschließt.< datei.txt
leitet den Inhalt von datei.txt
in die Standardeingabe (stdin) um.set /p meineVar= < datei.txt
bewirkt daher, dass Hallo Welt
aus der datei.txt
in die Variable meineVar
geschrieben wird.echo %meineVar%
gibt Hallo Welt
aus.3. Ausgaben von Ziffern umleiten
echo Text #> datei.txt
(#
steht hier für eine einzelne Ziffer und "Text"
ist optional und nicht relevant)Text
Nur bei #=1 landet
"Text "
in der Datei. Die Ziffer wird nirgends ausgegeben.Bei allen anderen Ziffern landet
"Text "
in der Console und die Ziffer nirgends.Um die besondere Funktion von
#>
zu umgehen kann man ein Leerzeichen einfügen # >
, doch dieses Leerzeichen landet dann auch im Umleitungsziel.Möchte man das Leerzeichen vermeiden, so gibt es diese Alternativen:
a)
(echo 1)> datei.txt
(den Befehl in Klammer setzen)b)
echo ^1> datei.txt
(die Ziffer mit Control-Zeichen maskieren)c)
echo.1> datei.txt
(die Ziffer steht nicht alleine da, sondern mit einem Punkt davor, sie wird daher anders behandelt. Siehe Kommentar)d)
echo> datei.txt 1
(die Umleitung schon vor die Ausgabe setzen)e)
>datei.txt echo 1
(die Umleitung schon ganz am Anfang setzen)fa)
(echo |set /p=1)> datei.txt & echo.>> datei.txt
(Wusste nicht so genau warum das funktioniert, aber das hat @Friemler in seinem Kommentar gut erläutert)fb)
(echo |set /p=1)> datei.txt
(schreibt eine "1" in die Datei ohne anschließenden Zeilenumbruch)Am eingängigsten finde ich b), da es bei anderen Dingen genauso funktioniert und mir entsprechend vertraut ist.
echo ^<br^>> datei.txt
(<br>
landet in der Datei)Kommentar zu c)
echo.
gibt eine Leerzeile aus.echo.Text
Folgt dem Leerzeilenausgabebefehl doch noch Text so wird er ausgegeben, statt der Leerzeile.Von der Verwendung von
echo.
ist allerdings abzuraten, da dabei echo
nicht sofort als interner Befehl erkannt und ausgeführt wird, sondern zuvor nach einer Datei namens echo
gesucht wird und das zuerst im aktuellen Verzeichnis und danach im gesamten Pfad. Erst dann wird der interne Befehl echo
ausgeführt.Aus Performancegründen ist
echo.
daher sehr nachteilig.Es hat aber auch noch Sicherheitsaspekte.
echo.cmd
sollte cmd
ausgeben und tut es auch, es sei denn, dass sich irgendwo im Pfad tatsächlich eine Datei namens echo.cmd
befindet.In dem Fall würde keine Ausgabe erfolgen, sondern diese
echo.cmd
gestartet werden.Im Falle von
echo.exe
wird eine Datei namens echo.exe
ausgeführt, wenn sie im aktuellen Verzeichnis vorliegt. Liegt sie dort nicht, sondern irgendwo im Pfad wird sie (inkonsequenterweise) nicht gestartet, sondern exe
ausgegeben.Wie auch immer, der Punkt hinter
echo
ist zu vermeiden.Es gibt dazu mehrere Alternativen und zu deren Risiken und Nebenwirkungen kann hier nachgelsen werden:
http://www.dostips.com/forum/viewtopic.php?t=774 und http://www.dostips.com/forum/viewtopic.php?t=1900
Die zu bevorzugenden Alternative ist die öffnende Klammer, also
echo(
- ohne Leerzeichen zwischen echo
und (
.Diese hat die wenigsten Nebenwirkungen. Der Kommandozeileninterpreter wertet sie nicht als öffnende Klammer in Klammerausdrücken eines Codes.
echo Test
versus echo(Text
Interessant ist das bei der Ausgabe von Zeilen, die nur aus Leerzeichen und/oder Tabs bestehen.
Ebenso interessant ist das bei der Ausgabe von Variablen die eventuell leer (nicht definiert) sind.
if "a"=="b" set ergebnis=merkwürdig
echo %ergebnis%
echo(%ergebnis%
set ergebnis=egal
echo %ergebnis%
echo(%ergebnis%
ECHO ist ausgeschaltet (OFF).
(da %ergebnis% leer/undefiniert ist, wurde echo
ohne Parameter aufgerufen und gibt daher seinen Zustand aus)Leerzeile
(da %ergebnis% leer/undefiniert ist, wurde echo(
aufgerufen und gibt daher eine Leerzeile aus)egal
(echo egal
liefert "egal")egal
(echo(egal
liefert auch "egal")Nebenbei erwähnt:
echo on
(schaltet das Echo an)echo(on
(gibt "on" aus)4. Zum Schluss das Ende
Eine Batchdatei endet, wenn sie ihre letzte Zeile abgearbeitet hat oder vorzeitig beendet oder verlassen wird.
Eine schlechte Möglichkeit zum vorzeitigen Beenden ist der Befehl
exit
Schlecht insofern, dass er nicht nur die Batch beendet, sondern auch die Eingabeaufforderung schließt, aus der man heraus die Batch gestartet hat.
Ruft man eine Batchdatei per
call
aus einer anderen Batchdatei heraus auf, würde das exit
in der aufgerufenen Batch auch die aufrufende Batch beenden, sodass das call
nutzlos wäre, weil die gesamte Ausführung beim ersten exit
endet.Schreibt man statt
exit
allerdings exit /b
so wird nur die Batch beendet, in der das exit /b
ausgeführt wird.a.cmd
@echo off
call b.cmd
echo Welt!
exit /b
b.cmd
@echo off
echo Hallo
exit /b
Will man
Hallo Welt!
als Ausgabe haben, so darf b.cmd
kein exit
(ohne /b
) enthalten.Anmerkung: In den Beispielen
a.cmd
und b.cmd
ist das exit /b
überflüssig, da es jeweils in der letzten Zeile steht und die Batches dort ohnhin enden.Eine weitere, gute Möglichkeit zum vorzeitigen Beenden ist der Befehl
goto :eof
(eof=End Of File). Wichtig ist hier der Doppelpunkt vor eof, denn ohne würde eine Sprungmarke namens eof gesucht werden und nicht das Dateiende.Ein Beispiel für ein vorzeitiges Beenden ist das hier:
@echo off
if %random% gtr 20000 exit /b
echo %random% ist ^<= 20000
if %random% lss 10000 goto :eof
echo %random% ist ^>= 10000
%random% liefert bei jedem Aufruf ein neues Zufallsergebnis.
Die Umleitungszeichen
>
und <
("nach" und "von") sind hier mit ^
maskiert, damit sie per echo ausgegeben und nicht als Umleitung verstanden werden.exit /b
und goto :eof
ist gleichwertig und in Batches gut verwendbar, da beides nur die jeweils aktuelle Batch beendet und nicht die gesamte Kette und auch nicht die Eingabeaufforderung, falls der Aufruf denn in einer solchen erfolgte.Ergänzend und optional kann man bei
exit /b
noch einen ExitCode mit angeben, der anschließend als %errorlevel%
zur Verfügung steht.exit /b 2
setzt den Errorlevel beispielsweise auf 2, wobei der angegebene Code auch eine Variable sein kann: exit /b %meinWert%
Gruß /b 0
Frank
PS: Danke für die konstruktiven Kommentare
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 336508
Url: https://administrator.de/contentid/336508
Ausgedruckt am: 24.11.2024 um 18:11 Uhr
5 Kommentare
Neuester Kommentar
Hallo Frank
vs.
http://www.dostips.com/forum/viewtopic.php?t=774
http://www.dostips.com/forum/viewtopic.php?t=1900
Es sei noch erwähnt, dass dies nicht nur für die Erzeugung von Leerzeilen interessant ist. Sollte eine Zeile nur aus Leerzeilen oder Tabs bestehen, ist das ebenso erforderlich.
EXIT /B (oder GOTO :EOF) ist nur für das Beenden von Codeteilen wichtig, bei dem nachfolgender Code nicht weiter verarbeiten werden soll. Bspw. für den Hauptcode, wenn noch Subroutinen folgen oder für das Beenden von mittels CALL aufgerufenen Subroutinen. Die Möglichkeit der Rückgabe eines Wertes bleibt natürlich ein valider Grund.
Grüße
rubberman
1. Zufalls-Zahl
Es ist richtig und gut die Berechnung mit 32768 statt mit Modulo durchzuführen, um das Ungleichgewicht von kleineren zu größeren Zahlen zu eliminieren. Zur Erklärung fehlt aber, dass Batch mittels SET /A nur Integeroperationen durchführen kann, was dazu führt, dass Nachkommastellen "abgeschnitten" werden (es findet auch keine Rundung statt). Das ist der Grund für das +1 in der Berechnung.2. Ausgaben umleiten
Es gäbe da noch < (Umleitung zum stdin). Das >> hast du im nächsten Abschnitt kurz angerissen, würde aber eher in Punkt 2 passen.3. Ausgaben von Ziffern umleiten
Ich empfehle grundsätzlich die Umleitung an den Anfang zu setzen. Das hilft nicht nur um das Deuten von Ziffern als Streamnummer zu vermeiden, sondern trägt auch wesentlich zur Lesbarkeit den Codes bei. Bsp.echo Hallo!>"test.txt"
echo Das ist eine Testzeile.>>"test.txt"
echo Und noch eine.>>"test.txt"
>"test.txt" echo Hallo!
>>"test.txt" echo Das ist eine Testzeile.
>>"test.txt" echo Und noch eine.
Kommentar zu c)
ECHO. ist der Worst Case. Es ist unsicher und langsam, da bei jedem Aufruf nach einer Datei mit Name echo gesucht wird. Nutze statt dessen ECHO( ohne Leerzeichen zwischen ECHO und der öffnenden Klammer. Diese hat die wenigsten Nebenwirkungen. Keine Angst, der Kommandozeileninterpreter zählt sie nicht als öffnende Klammer in Klammerausdrücken des Codes. Referenzenhttp://www.dostips.com/forum/viewtopic.php?t=774
http://www.dostips.com/forum/viewtopic.php?t=1900
Es sei noch erwähnt, dass dies nicht nur für die Erzeugung von Leerzeilen interessant ist. Sollte eine Zeile nur aus Leerzeilen oder Tabs bestehen, ist das ebenso erforderlich.
4. Zum Schluss das Ende
Grundsätzlich wird weder EXIT noch EXIT /B benötigt. Die Abarbeitung des Scripts endet nach der letzten Zeile des Scripts. Sollte sich die Scriptausführung nicht selbständig beenden, so liegt das am falschen Aufruf des Scripts.EXIT /B (oder GOTO :EOF) ist nur für das Beenden von Codeteilen wichtig, bei dem nachfolgender Code nicht weiter verarbeiten werden soll. Bspw. für den Hauptcode, wenn noch Subroutinen folgen oder für das Beenden von mittels CALL aufgerufenen Subroutinen. Die Möglichkeit der Rückgabe eines Wertes bleibt natürlich ein valider Grund.
Grüße
rubberman
Hallo Frank,
Der
Der Text "
Außerdem kann die Standardeingabe von
Ob gewollt oder wegen eines schlecht programmierten Parsers kann
gibt nur den Text "
Somit lässt sich Dein Beispiel fa) folgendermaßen erklären:
Bei Deinem Beispiel fb) fehlt der letzte Schritt.
Grüße
Friemler
Zitat von @Pedant:
fa)
fb)
fa)
(echo |set /p=1)> datei.txt & echo.>> datei.txt
(Weiß nicht so genau warum das funktioniert)fb)
(echo |set /p=1)> datei.txt
(schreibt eine "1" in die Datei ohne anschließenden Zeilenumbruch)Der
SET
-Befehl mit der Option /p
dient eigentlich dazu, Benutzereingaben zu erfassen und einer Umgebungsvariablen zuzuweisen:set /p "Name=Geben sie den Benutzernamen ein: "
Der Text "
Geben sie den Benutzernamen ein:
" (ohne Anführungszeichen) wird als Prompt/Eingabeaufforderung ausgegeben und dann auf eine Benutzereingabe gewartet, die mit ENTER
abgeschlossen werden muss. Die Eingabe steht danach in der Umgebungsvariablen Name
zur Verfügung (wenn man %Name%
schreibt).Außerdem kann die Standardeingabe von
SET /p
umgeleitet werden (auf ein anderes Device, eine Datei oder eine Pipe).Ob gewollt oder wegen eines schlecht programmierten Parsers kann
SET /p
aber auch zur reinen Ausgabe von Text ohne abschließenden Zeilenumbruch missbraucht werden. Der Befehl<NUL set /p "=Geben Sie den Benutzernamen ein: "
Geben Sie den Benutzernamen ein:
" aus (ohne Anführungszeichen und ohne abschließenden Zeilenumbruch). Da die Standardeingabe auf das NUL Device umgeleitet ist, ließt SET /p
seine Eingabe von dort. Das NUL Device liefert natürlich immer nur END OF STREAM
zurück, wodurch die Eingabe abgeschlossen wird. Da vor dem Gleichheitszeichen kein Variablennamen angegeben ist, wird die (sowieso leere) Eingabe nirgends gespeichert.Somit lässt sich Dein Beispiel fa) folgendermaßen erklären:
- Der
ECHO
-Befehl ingibt den(echo |set /p=1)
ECHO
-Status und einen Zeilenumbruch auf der Standardausgabe aus, die über eine Pipe in die Standardeingabe desSET /p
Befehls geschrieben werden. - Dieser Befehl gibt zunächst die
1
rechts vom Gleichheitszeichen auf seiner Standardausgabe aus und ließt dann von seiner Standardeingabe (der Pipe) die Ausgabe desECHO
Befehls. Da diese mit einem Zeilenumbruch endet, gilt sie als abgeschlossen und derSET
Befehl wird beendet. Die über die Pipe gelesene Ausgabe desECHO
-Status wird in Ermangelung einer Variablen links vom Gleichheitszeichen verschluckt. - Die Ausgabe des
SET
Befehls (die1
) wird per Ausgabeumleitung in die Dateidatei.txt
geschrieben. - Anschließend wird durch den Befehlsverkettungsoperator
&
der Befehlausgeführt, der einen Zeilenumbruch an die Dateiecho.>> datei.txt
datei.txt
anhängt.
Bei Deinem Beispiel fb) fehlt der letzte Schritt.
Grüße
Friemler
Hallo Frank,
nein, nein. Ich hatte fb) im Zitat stehen, da wollte ich halt auch noch etwas dazu sagen.
N8
Friemler
nein, nein. Ich hatte fb) im Zitat stehen, da wollte ich halt auch noch etwas dazu sagen.
N8
Friemler