set /p innerhalb von if
fehlermeldung bei der kombi von if + set /p
hallo.
ich beschäftige mich, auf grund der notwendigkeit, seit 2 tagen mit dem batch syntax. nun habe ich ein kleines batchfile geschrieben, mit dem ich das starten von anwendungen kontrolliere, bei bedarf reg schlüssel auslese und falls diese nicht vorhanden sind, eine manuelle eingabe der benötigten daten starte.
nun habe ich schon google und das forum hier durchsucht, allerdings nur allgemeine sachen über set und if gefunden. aus der windows hilfe habe ich alles gelernt über die wichtigsten befehle, scheitere jedoch trozdem an einem scheinbar lächerlichem punkt.
hier erstmal der quellcode, den ich mit hilfe des cmd-fensters als fehlerhaft lokalisieren konnte:
if (%msel%)==(1) set mdir=path1
if (%msel%)==(2) set mdir=path2
if (%msel%)==(3) set mdir=xy
if (%msel%)==(4) set mdir=path3
) ELSE (
echo auto-detected dir...
::noch paar andere cmds
)
::usw
echo.
echo mdir: %mdir%
pause
</font>
der cmd in rot wird nie ausgeführt.
der code gibt folgende meldung:
wenn ich die klammern weg lasse und/oder vorher einen wert für msel definiere geht es auch nicht bzw. es wird auf eine eingabe gewartet und dann doch der vordefinierte wert verwendet.
einzeln funktionieren ja die befehle (die if-prüfung für sich, sowie das menü mit eingabe für sich), aber zusammen eben nicht.... *schnief*
naja.... bin eben doch noch en ganz schöner nup...
mfg... das kleine yashi
hallo.
ich beschäftige mich, auf grund der notwendigkeit, seit 2 tagen mit dem batch syntax. nun habe ich ein kleines batchfile geschrieben, mit dem ich das starten von anwendungen kontrolliere, bei bedarf reg schlüssel auslese und falls diese nicht vorhanden sind, eine manuelle eingabe der benötigten daten starte.
nun habe ich schon google und das forum hier durchsucht, allerdings nur allgemeine sachen über set und if gefunden. aus der windows hilfe habe ich alles gelernt über die wichtigsten befehle, scheitere jedoch trozdem an einem scheinbar lächerlichem punkt.
hier erstmal der quellcode, den ich mit hilfe des cmd-fensters als fehlerhaft lokalisieren konnte:
@echo off & setlocal
set mdir=test
:: zwecks test in extra batchfile
if /i (%mdir%)==(test) (
echo here comes the menu
echo 1 bla
echo 2 bla
echo input ?
<font color="#ff0000">set /p msel=
if (%msel%)==(2) set mdir=path2
if (%msel%)==(3) set mdir=xy
if (%msel%)==(4) set mdir=path3
) ELSE (
echo auto-detected dir...
::noch paar andere cmds
)
::usw
echo.
echo mdir: %mdir%
pause
</font>
der cmd in rot wird nie ausgeführt.
der code gibt folgende meldung:
")" ist syntaktisch an dieser Stelle nicht verarbeitbar.
C:\batch>if ()==(1) set mdir=path1
einzeln funktionieren ja die befehle (die if-prüfung für sich, sowie das menü mit eingabe für sich), aber zusammen eben nicht.... *schnief*
naja.... bin eben doch noch en ganz schöner nup...
mfg... das kleine yashi
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 26294
Url: https://administrator.de/contentid/26294
Ausgedruckt am: 26.11.2024 um 10:11 Uhr
12 Kommentare
Neuester Kommentar
Moin yashi,
da scheint de CMD-Prompt wirklich ein Problem zu haben.. muss ich mir mal in Ruhe ansehen.
Das wäre dann ja schon Bug #4033 auf meiner Liste... *gg
Also - Du hast da nichts verkehrt gemacht und dokumentiert ist dieses Verhalten auch nicht.
Du kannst es auf mehrere Arten umgehen, empfehlen würde ich die wenig elegante mit "goto":
::------------------
echo off & setlocal
set mdir=test
:: zwecks test in extra batchfile
echo input ?
if /i [%mdir%]==[test] goto getAuswahl
goto autodetect
:getauswahl
echo here comes the menu
echo 1 bla
echo 2 bla
echo input ?
set /p "msel=bla"
if [%msel%]==[1] set mdir=path1
if [%msel%]==[2] set mdir=path2
if [%msel%]==[3] set mdir=xy
if [%msel%]==[4] set mdir=path3
goto undweiter
:autodetect
echo auto-detected dir...
::noch paar andere cmds
:undweiter
::usw
:: ....
::------------
Um andere Konflikte zu vermeiden, habe ich die "runden Klammern" bei den IF-Vergleichen durch eckige ersetzt. Runde Klammern sind eben auch Steuerzeichen im Batch... aber das hat mit dem SET /P-Effekt, der Dir aufgefallen war, nichts zu tun.
Gruß Biber
da scheint de CMD-Prompt wirklich ein Problem zu haben.. muss ich mir mal in Ruhe ansehen.
Das wäre dann ja schon Bug #4033 auf meiner Liste... *gg
Also - Du hast da nichts verkehrt gemacht und dokumentiert ist dieses Verhalten auch nicht.
Du kannst es auf mehrere Arten umgehen, empfehlen würde ich die wenig elegante mit "goto":
::------------------
echo off & setlocal
set mdir=test
:: zwecks test in extra batchfile
echo input ?
if /i [%mdir%]==[test] goto getAuswahl
goto autodetect
:getauswahl
echo here comes the menu
echo 1 bla
echo 2 bla
echo input ?
set /p "msel=bla"
if [%msel%]==[1] set mdir=path1
if [%msel%]==[2] set mdir=path2
if [%msel%]==[3] set mdir=xy
if [%msel%]==[4] set mdir=path3
goto undweiter
:autodetect
echo auto-detected dir...
::noch paar andere cmds
:undweiter
::usw
:: ....
::------------
Um andere Konflikte zu vermeiden, habe ich die "runden Klammern" bei den IF-Vergleichen durch eckige ersetzt. Runde Klammern sind eben auch Steuerzeichen im Batch... aber das hat mit dem SET /P-Effekt, der Dir aufgefallen war, nichts zu tun.
Gruß Biber
@maneich
Stimmt, ich hatte es auch auf das "Set /p" geschoben.
Ursachen sind zwei:
1) beim ersten "Set mdir=... ist ein Leerzeichen dahinter.
Also steht da "in Wirklichkeit
Set "mdir=test " und das führt zu Fehlinterpretation bei
IF (test )==(test) ...
2) Zweite Ursache... Die runden Klammern als Trennzeichen in den IF-Vergleichen.
Folgendes Codefragment läuft (runde Klammern der IFs durch "x" ersetzt; SETs glattgezogen):
::--------------yashis.bat
@echo off & setlocal
set "mdir=test"
:: zwecks test in extra batchfile
if /i x%mdir%x==xtestx (
echo here comes the menu
echo 1 bla
echo 2 bla
echo input ?
set /p msel=
if x%msel%x==x1x set mdir=path1
if x%msel%x==x2x set mdir=path2
if x%msel%x==x3x set mdir=xy
if x%msel%x==x4x set mdir=path3
) ELSE (
echo auto-detected dir...
REM noch paar andere cmds
)
::usw
echo.
echo mdir: %mdir%
pause
::--------------yashis.bat
Gruß Biber
Stimmt, ich hatte es auch auf das "Set /p" geschoben.
Ursachen sind zwei:
1) beim ersten "Set mdir=... ist ein Leerzeichen dahinter.
Also steht da "in Wirklichkeit
Set "mdir=test " und das führt zu Fehlinterpretation bei
IF (test )==(test) ...
2) Zweite Ursache... Die runden Klammern als Trennzeichen in den IF-Vergleichen.
Folgendes Codefragment läuft (runde Klammern der IFs durch "x" ersetzt; SETs glattgezogen):
::--------------yashis.bat
@echo off & setlocal
set "mdir=test"
:: zwecks test in extra batchfile
if /i x%mdir%x==xtestx (
echo here comes the menu
echo 1 bla
echo 2 bla
echo input ?
set /p msel=
if x%msel%x==x1x set mdir=path1
if x%msel%x==x2x set mdir=path2
if x%msel%x==x3x set mdir=xy
if x%msel%x==x4x set mdir=path3
) ELSE (
echo auto-detected dir...
REM noch paar andere cmds
)
::usw
echo.
echo mdir: %mdir%
pause
::--------------yashis.bat
Gruß Biber
Moin yashi,
schön, mal wieder von Dir zu lesen...
Also, wenn mein oben geposteter Batchschnipsel NICHT läuft, dann kommt es durch das Copy & Paste'n .. ersetze bitte die Zeile
ALT: set /p msel=
-durch-
NEU: set /p "msel="
Denn dann ist da wieder ein trailing blank hinter. Darauf wette ich alle Rosen, die ich zum Valentinstag geschenktz bekommen habe.
Die zweite Frage:
Wie häufig bei M$-Programmen ein klares "Jein".
Die CMD.exe kennt nur Strings...eigentlich ... also weder den Datentyp "Datum" oder "Long" oder "Integer"....ABER:
Wenn einer der beiden verglichenen Werte "eindeutig" numerisch ist, d.h. über "Set /a" als Zahlenwert erzwungen, dann wird auch der zweite Wert auf Numerisch geCASTet.
Heißt in der Konsequenz allerdings auch wieder nur Wischiwaschi..(ist halt M$):
einen mit "Set /a" definierten Wert von "4711" kannst Du mit LSS,GEQ, GTR etc vergleichen...
Aber auch einschließen....
Und irgendwann ist es aber nicht mehr einleuchtend:
Deine Beispielzeile "if x%var%x LEQ x10x funktioniert also, aber ich würde sie schon so formulieren:
If %var% LEQ 10 Echo var ist kleiner gleich 10
-oder-
Set /a var+=0 >nul
If Errorlevel 1 (
echo Variable var hat keinen numerischen Wert!
) ELSE (
If %var% LEQ 10 Echo var ist kleiner gleich 10!
)
Schönes Wochenende
Biber
schön, mal wieder von Dir zu lesen...
Also, wenn mein oben geposteter Batchschnipsel NICHT läuft, dann kommt es durch das Copy & Paste'n .. ersetze bitte die Zeile
ALT: set /p msel=
-durch-
NEU: set /p "msel="
Denn dann ist da wieder ein trailing blank hinter. Darauf wette ich alle Rosen, die ich zum Valentinstag geschenktz bekommen habe.
Die zweite Frage:
wenn ich 2 werte vergleiche, und diese in symbole einschließe, werden doch daraus strings oder ?
also dürfte dann sowas wie
if x%var%x LEQ x10x ....
nicht funktionieren ?! ..
also dürfte dann sowas wie
if x%var%x LEQ x10x ....
nicht funktionieren ?! ..
Die CMD.exe kennt nur Strings...eigentlich ... also weder den Datentyp "Datum" oder "Long" oder "Integer"....ABER:
Wenn einer der beiden verglichenen Werte "eindeutig" numerisch ist, d.h. über "Set /a" als Zahlenwert erzwungen, dann wird auch der zweite Wert auf Numerisch geCASTet.
Heißt in der Konsequenz allerdings auch wieder nur Wischiwaschi..(ist halt M$):
einen mit "Set /a" definierten Wert von "4711" kannst Du mit LSS,GEQ, GTR etc vergleichen...
Set /a "test=47"
if %test% LSS 77 @echo Ist kleiner!
Ist kleiner!Aber auch einschließen....
if x%test%x LSS x77x @echo Ist kleiner!
Ist kleiner!Und irgendwann ist es aber nicht mehr einleuchtend:
if x%test%x lss xeex @echo Ist kleiner!
Ist kleiner!if %test% lss ee @echo Ist kleiner!
Ist kleiner!if %test% lss 000000000 @echo Ist kleiner!
if %test% lss 47e @echo Ist kleiner!
Ist kleiner!Deine Beispielzeile "if x%var%x LEQ x10x funktioniert also, aber ich würde sie schon so formulieren:
If %var% LEQ 10 Echo var ist kleiner gleich 10
-oder-
Set /a var+=0 >nul
If Errorlevel 1 (
echo Variable var hat keinen numerischen Wert!
) ELSE (
If %var% LEQ 10 Echo var ist kleiner gleich 10!
)
Schönes Wochenende
Biber
Hallo,
im grunde genommen setzt Du auf beiden Seiten der Abfrage ja das/die gleichen Zeichen ein, damit die Abfrage auch immer klappt. Existiert die Variable nicht, bekommst Du ohne zusätzliche Zeichen einen Syntaxerror.
Wenn Du also sicher sein kannst daß die Variable existent ist, brauchst Du diese zusätzlichen Zeichen nicht.
Warum das bei Dir nicht läuft, kann ich auch nicht sagen. Du kannst ja mal ff. versuchen:
if /i x%mdir%x==xtestx (
echo here comes the menu
echo 1 bla
echo 2 bla
echo input ?
set /p msel=
echo %msel%
pause
Um überhaupt mal zu wissen ob und was nach der Eingabe drinnsteht.
MfG maneich
im grunde genommen setzt Du auf beiden Seiten der Abfrage ja das/die gleichen Zeichen ein, damit die Abfrage auch immer klappt. Existiert die Variable nicht, bekommst Du ohne zusätzliche Zeichen einen Syntaxerror.
Wenn Du also sicher sein kannst daß die Variable existent ist, brauchst Du diese zusätzlichen Zeichen nicht.
Warum das bei Dir nicht läuft, kann ich auch nicht sagen. Du kannst ja mal ff. versuchen:
if /i x%mdir%x==xtestx (
echo here comes the menu
echo 1 bla
echo 2 bla
echo input ?
set /p msel=
echo %msel%
pause
Um überhaupt mal zu wissen ob und was nach der Eingabe drinnsteht.
MfG maneich
Hallo,
nun ja, die if...else Konstruktion ist in sich geschlossen 1 Befehlssatz und in Deinem letzten Beispiel ist die Syntax eben in diesem Befehlssatz falsch.
Ob dieser Befehlssatz über eine Zeile
if %a%==%b% (goto :x) else (goto :y)
oder über mehrere Zeilen, wie in deiner Batch, aufgebaut ist, ist dabei unwesentlich. Es ist und bleibt 1 Befehlssatz
Bei der goto ... Konstruktion wird die falsche Syntax-Zeile ungeprüft übersprungen, da dies dann ein neuer Befehlssatz ist.
Mache einfach mal folgendes:
@echo off
set mdir=test
:: zwecks test in extra batchfile
if not (%mdir%)==(test) goto nr2
echo here comes the menu
echo 1 bla
echo 2 bla
echo input ?
set /p msel=
if (%msel%)==(1) set mdir=path1
if (%msel%)==(2) set mdir=path2
if (%msel%)==(3) set mdir=xy
if (%msel%)==(4) set mdir=path3
goto usw
:nr2
echo auto-detected dir...
::noch paar andere cmds
:usw
echo.
echo mdir: %mdir%
pause
Mal sehen, was dann passiert. Der Parameter /i bei if ist in Deinem Fall nicht unbeding nötig. Das setlocal ebenfalls mal weglassen.
Ich denke, daß setlocal der Variablen zwar den Wert "test" übergibt aber ohne endlocal keine Änderung möglich ist. Würde ich mal als erstes testen in Deiner ursprünglichen Batch, ist hier auch nicht wesentlich.
MfG maneich
nun ja, die if...else Konstruktion ist in sich geschlossen 1 Befehlssatz und in Deinem letzten Beispiel ist die Syntax eben in diesem Befehlssatz falsch.
Ob dieser Befehlssatz über eine Zeile
if %a%==%b% (goto :x) else (goto :y)
oder über mehrere Zeilen, wie in deiner Batch, aufgebaut ist, ist dabei unwesentlich. Es ist und bleibt 1 Befehlssatz
Bei der goto ... Konstruktion wird die falsche Syntax-Zeile ungeprüft übersprungen, da dies dann ein neuer Befehlssatz ist.
Mache einfach mal folgendes:
@echo off
set mdir=test
:: zwecks test in extra batchfile
if not (%mdir%)==(test) goto nr2
echo here comes the menu
echo 1 bla
echo 2 bla
echo input ?
set /p msel=
if (%msel%)==(1) set mdir=path1
if (%msel%)==(2) set mdir=path2
if (%msel%)==(3) set mdir=xy
if (%msel%)==(4) set mdir=path3
goto usw
:nr2
echo auto-detected dir...
::noch paar andere cmds
:usw
echo.
echo mdir: %mdir%
pause
Mal sehen, was dann passiert. Der Parameter /i bei if ist in Deinem Fall nicht unbeding nötig. Das setlocal ebenfalls mal weglassen.
Ich denke, daß setlocal der Variablen zwar den Wert "test" übergibt aber ohne endlocal keine Änderung möglich ist. Würde ich mal als erstes testen in Deiner ursprünglichen Batch, ist hier auch nicht wesentlich.
MfG maneich
Moin yashi,
so was... erst tagelang nicht um angefangene Threads kümmern und dann auf meine Rosen schielen... *tztztz
Aber recht hattest Du - es lag diesmal nicht an trailing blanks - ich hätte mir auch die Mühe machen können, diese Schnipsel mal laufen zu lassen. Oder zumindest Deinen Titel laut und deutlich vor mich hinzusprechen. Das hab ich jetzt.
a) der Syntaxfehler bei "if if if --tilt" hat mich drauf gebracht: Auch wenn Dein IF (..)..ELSE (..) - Konstrukt über noch so viele Zeilen gestreckt ist - der CMD-Interpreter fasst es immer noch als eine Zeile auf.
Entsprechend liest er alles bis zur Klammer-Zu en bloc ein, macht seinen Syntaxcheck und führt es dann aus. Bzw. bei Dir kommt er eben nur bis zum Syntaxcheck und meckert dann. Zu recht. Nicht beim Ausführen, wie Du unterstellt hast, sondern einen Schritt vorher, beim Parsen, beim Syntaxcheck. Wenn Du ein "REM" vor das "if if if" setzt, dann passiert er den Syntaxcheck.
if 123==987 (
echo true
rem if if if ... i fail -.-
) ELSE (
echo false
)
echo end
echo.
pause
b) Und - dadurch, dass das IF-Konstrukt EINE Zeile ist, werden "natürlich" alle darin enthaltenen Variablen EINMAL, beim "Einlesen" der einen Zeile aufgelöst. Auch die Variable %msel%, die ja durch das "Set /p msel="einen neuen Wert bekommt. Der wird aber innerhalb der IF-Verzweigung nicht neu aktualisiert, es sei denn, bei Dir ist die so genannte verzögerte Variablenauflösung aktiviert.
So macht der Code-Schnipsel das was Du willst:
:: --- snipp yashisIfMselMitDelayedExpansion.bat
@echo off & setlocal EnableDelayedExpansion
set "mdir=test"
if /i x%mdir%x==xtestx (
rem --verschoben in das Set /p-- echo menu.input ?
set /p "msel=menu.input ?"
if x!msel!x==x1x echo 1
if x!msel!x==x2x set "mdir=path2"
if x!msel!x==x3x set "mdir=path3"
if x!msel!x==x4x set "mdir=path4"
) ELSE (
echo auto-detected dir...
)
echo mdir: %mdir%
echo msel: %msel%
pause
:: --- snapp yashisIfMselMitDelayedExpansion.bat
Entscheidend ist in der ersten Zeile: @echo off & setlocal EnableDelayedExpansion
...und etwas tiefer die !var! statt %var%-Syntax bei den Variablen, die Du "verspätet" auflösen willst.
( Anmerkung: die Änderung ..
rem --verschoben in das Set /p-- echo menu.input ?
set /p "msel=menu.input ?"
... hat inhaltlich nichts damit so tun... das war nur die Umsetzung von maneichs Anregung einen halben Meter weiter oben.)
Und das "Einschließen" der VBariablen mit einem beliebigen Buchstaben/Zeichen wie z.B. "x" war nur ein Beispiel.
Ich würde aus Lesbarkeitsgrunden nie schreiben:
if x!msel!x==x1x echo 1
if x!msel!x==x2x set "mdir=path2"
if x!msel!x==x3x set "mdir=path3"
if x!msel!x==x4x set "mdir=path4"
--sondern:
if [!msel!]==[1] echo 1
if [!msel!]==[2] set "mdir=path2"
if [!msel!]==[3] set "mdir=path3"
if [!msel!]==[4] set "mdir=path4"
HTH Biber
[Edit] @maneich
uuups, da warst ja zwischendurch schon wieder schneller.. na ja, ich habe nebenbei noch Mittagessen gekocht..*gg
Dein Kommentar war noch nicht da, als ich angefangen hatte..
[/Edit]
so was... erst tagelang nicht um angefangene Threads kümmern und dann auf meine Rosen schielen... *tztztz
Aber recht hattest Du - es lag diesmal nicht an trailing blanks - ich hätte mir auch die Mühe machen können, diese Schnipsel mal laufen zu lassen. Oder zumindest Deinen Titel laut und deutlich vor mich hinzusprechen. Das hab ich jetzt.
a) der Syntaxfehler bei "if if if --tilt" hat mich drauf gebracht: Auch wenn Dein IF (..)..ELSE (..) - Konstrukt über noch so viele Zeilen gestreckt ist - der CMD-Interpreter fasst es immer noch als eine Zeile auf.
Entsprechend liest er alles bis zur Klammer-Zu en bloc ein, macht seinen Syntaxcheck und führt es dann aus. Bzw. bei Dir kommt er eben nur bis zum Syntaxcheck und meckert dann. Zu recht. Nicht beim Ausführen, wie Du unterstellt hast, sondern einen Schritt vorher, beim Parsen, beim Syntaxcheck. Wenn Du ein "REM" vor das "if if if" setzt, dann passiert er den Syntaxcheck.
if 123==987 (
echo true
rem if if if ... i fail -.-
) ELSE (
echo false
)
echo end
echo.
pause
b) Und - dadurch, dass das IF-Konstrukt EINE Zeile ist, werden "natürlich" alle darin enthaltenen Variablen EINMAL, beim "Einlesen" der einen Zeile aufgelöst. Auch die Variable %msel%, die ja durch das "Set /p msel="einen neuen Wert bekommt. Der wird aber innerhalb der IF-Verzweigung nicht neu aktualisiert, es sei denn, bei Dir ist die so genannte verzögerte Variablenauflösung aktiviert.
So macht der Code-Schnipsel das was Du willst:
:: --- snipp yashisIfMselMitDelayedExpansion.bat
@echo off & setlocal EnableDelayedExpansion
set "mdir=test"
if /i x%mdir%x==xtestx (
rem --verschoben in das Set /p-- echo menu.input ?
set /p "msel=menu.input ?"
if x!msel!x==x1x echo 1
if x!msel!x==x2x set "mdir=path2"
if x!msel!x==x3x set "mdir=path3"
if x!msel!x==x4x set "mdir=path4"
) ELSE (
echo auto-detected dir...
)
echo mdir: %mdir%
echo msel: %msel%
pause
:: --- snapp yashisIfMselMitDelayedExpansion.bat
Entscheidend ist in der ersten Zeile: @echo off & setlocal EnableDelayedExpansion
...und etwas tiefer die !var! statt %var%-Syntax bei den Variablen, die Du "verspätet" auflösen willst.
( Anmerkung: die Änderung ..
rem --verschoben in das Set /p-- echo menu.input ?
set /p "msel=menu.input ?"
... hat inhaltlich nichts damit so tun... das war nur die Umsetzung von maneichs Anregung einen halben Meter weiter oben.)
Und das "Einschließen" der VBariablen mit einem beliebigen Buchstaben/Zeichen wie z.B. "x" war nur ein Beispiel.
Ich würde aus Lesbarkeitsgrunden nie schreiben:
if x!msel!x==x1x echo 1
if x!msel!x==x2x set "mdir=path2"
if x!msel!x==x3x set "mdir=path3"
if x!msel!x==x4x set "mdir=path4"
--sondern:
if [!msel!]==[1] echo 1
if [!msel!]==[2] set "mdir=path2"
if [!msel!]==[3] set "mdir=path3"
if [!msel!]==[4] set "mdir=path4"
HTH Biber
[Edit] @maneich
uuups, da warst ja zwischendurch schon wieder schneller.. na ja, ich habe nebenbei noch Mittagessen gekocht..*gg
Dein Kommentar war noch nicht da, als ich angefangen hatte..
[/Edit]
Danke, yashi,
so macht die gemeinsame Lösungssuche Spaß..
Sagen wir so... es ist offensichtlich mit etwas heißer Nadel gestrickt, was die "neue" CMD.exe so alles kann seit W2k..
Vieles ist so grottig schlecht implementiert (die haarsträubendsten Beispiele: Die "Set /a"-Rechenfunktion, die "Maskierung" von Steuerzeichen, das Verhalten von "Echo" beim Aufrufen von Unter-Bätchen, die trailing blanks bei Variablen und eben auch diese DelayedExpansion-Schalter...), dass es sich definitiv nicht "sauber"=im Vertrauen auf die Vollständigkeit der Dokumentation benutzen lässt.
Ich habe neulich grad in meinem (Lieblings-) Batch-Tut III "Datums- und Zeitvariablen" ja wieder mühselig um diese Bugs? Features? herumgecoded.
Dennoch: das Positive überwiegt für mich. Nach meiner Wahrnehmung wurde vor wenigen Jahren von M$ suggeriert, dass jegliche Konsolen-Eingabe im 21. Jahrhundert vollkommen überflüssig/alles antiquierter oder nostalgischer Kram wäre, dem auf Grund der Altersstruktur der mit DOS 2.11 eingestiegenen ITler auch in absehbarer Zeit die Fans wegschmelzen würden...
Seit Win NT/W2K ist gottseidank auch in Redmond die Einsicht da, dass möglicherweise mit Klicki-Bunti nicht alles sinnvoll erledigt werden kann. Und die ganz, ganz lieblosen Beta-Beta-Konsolenutilities, die nach dem Motto "Vollkommen egal, ist eh in drei Jahren alles Geschichte" zusammengeschreddert waren, sind wieder raus aus dem Lieferumfang (ich erinnere an choice.com oder ForFiles.exe).
Dafür sind viele frühere ResKit-Utilities jetzt auf der normalen Anwender-CD dabei. Und ziemlich jedes GUI-Programm hat inzwischen einen /Silent-Schalter bzw. einen Batch-Modus.
Ich finde es also all in all schon gut, dass ein paar "echte Erweiterungen" reingebracht worden - richtig deutlich wird das bei den Fragestellern, die zum Beispiel noch mit Win98 arbeiten und eben mal schnell Tag-Monat-Jahr in einen Log-Filenamen einbauen wollen.. so etwas war schlicht und einfach nicht ohne Verrenkungen möglich vor Win2k.
Und dafür nehme ich gewisse Programmierschwächen bei den Redmondern in Kauf.
Mein Lieblingsbeispiele zum Klarmachen der "DelayedExpansion" ist übrigens auch wieder ein Oneliner-Batch.
::---snipp DelayedDemo.bat -------------
@setlocal EnableDelayedExpansion & @for /l %%i in (1,1,5) do @echo RandomNotDelayed:[%random%] RandomDelayed:[!random!]
::---snipp DelayedDemo.bat -------------
Output:
$cmd$ DelayedDemo.bat
RandomNotDelayed:[2041] RandomDelayed:[13891]
RandomNotDelayed:[2041] RandomDelayed:[5397]
RandomNotDelayed:[2041] RandomDelayed:[6209]
RandomNotDelayed:[2041] RandomDelayed:[22982]
RandomNotDelayed:[2041] RandomDelayed:[30280]
Ich denke, damit wird es dann klar. "Ein Batch sagt mehr als 1000 Worte". *sfg
Und die zweite Frage
Da hatte ich auch mal ein Gegenbeispiel in einem meiner Tutorials... alles zwischen zwei Ausrufungszeichen wird als Variable "aufgelöst", wenn DelayedExpansion aktiv ist. Aus ..
Echo Microsoft! You 're the best - f*ck the rest!
wird in der Anzeige schlicht
Microsoft
Und selbst "einfache Ausrufungszeichen" am Ende einer Fehlermeldung kann ich mit DelayedExpansion nicht einfach anzeigen:
echo Backup failed!
wird zu
Backup failed
Deshalb möchte ich eigentlich gar nicht, dass M$ bzw. die CMD.exe irgendetwas automatisch zu erkennen versucht..*gg
Bis zum nächsten Batch
Frank / der Biber aus Bremen
so macht die gemeinsame Lösungssuche Spaß..
verzögerte Variablenauflösung - Fluch, oder Segen ? ^^
Sagen wir so... es ist offensichtlich mit etwas heißer Nadel gestrickt, was die "neue" CMD.exe so alles kann seit W2k..
Vieles ist so grottig schlecht implementiert (die haarsträubendsten Beispiele: Die "Set /a"-Rechenfunktion, die "Maskierung" von Steuerzeichen, das Verhalten von "Echo" beim Aufrufen von Unter-Bätchen, die trailing blanks bei Variablen und eben auch diese DelayedExpansion-Schalter...), dass es sich definitiv nicht "sauber"=im Vertrauen auf die Vollständigkeit der Dokumentation benutzen lässt.
Ich habe neulich grad in meinem (Lieblings-) Batch-Tut III "Datums- und Zeitvariablen" ja wieder mühselig um diese Bugs? Features? herumgecoded.
Dennoch: das Positive überwiegt für mich. Nach meiner Wahrnehmung wurde vor wenigen Jahren von M$ suggeriert, dass jegliche Konsolen-Eingabe im 21. Jahrhundert vollkommen überflüssig/alles antiquierter oder nostalgischer Kram wäre, dem auf Grund der Altersstruktur der mit DOS 2.11 eingestiegenen ITler auch in absehbarer Zeit die Fans wegschmelzen würden...
Seit Win NT/W2K ist gottseidank auch in Redmond die Einsicht da, dass möglicherweise mit Klicki-Bunti nicht alles sinnvoll erledigt werden kann. Und die ganz, ganz lieblosen Beta-Beta-Konsolenutilities, die nach dem Motto "Vollkommen egal, ist eh in drei Jahren alles Geschichte" zusammengeschreddert waren, sind wieder raus aus dem Lieferumfang (ich erinnere an choice.com oder ForFiles.exe).
Dafür sind viele frühere ResKit-Utilities jetzt auf der normalen Anwender-CD dabei. Und ziemlich jedes GUI-Programm hat inzwischen einen /Silent-Schalter bzw. einen Batch-Modus.
Ich finde es also all in all schon gut, dass ein paar "echte Erweiterungen" reingebracht worden - richtig deutlich wird das bei den Fragestellern, die zum Beispiel noch mit Win98 arbeiten und eben mal schnell Tag-Monat-Jahr in einen Log-Filenamen einbauen wollen.. so etwas war schlicht und einfach nicht ohne Verrenkungen möglich vor Win2k.
Und dafür nehme ich gewisse Programmierschwächen bei den Redmondern in Kauf.
Mein Lieblingsbeispiele zum Klarmachen der "DelayedExpansion" ist übrigens auch wieder ein Oneliner-Batch.
::---snipp DelayedDemo.bat -------------
@setlocal EnableDelayedExpansion & @for /l %%i in (1,1,5) do @echo RandomNotDelayed:[%random%] RandomDelayed:[!random!]
::---snipp DelayedDemo.bat -------------
Output:
$cmd$ DelayedDemo.bat
RandomNotDelayed:[2041] RandomDelayed:[13891]
RandomNotDelayed:[2041] RandomDelayed:[5397]
RandomNotDelayed:[2041] RandomDelayed:[6209]
RandomNotDelayed:[2041] RandomDelayed:[22982]
RandomNotDelayed:[2041] RandomDelayed:[30280]
Ich denke, damit wird es dann klar. "Ein Batch sagt mehr als 1000 Worte". *sfg
Und die zweite Frage
Naja ich frag mich, warum die cmd.exe die Notwendigkeit dieser Funktion nicht automatisch erkennt und aktiviert.
Da hatte ich auch mal ein Gegenbeispiel in einem meiner Tutorials... alles zwischen zwei Ausrufungszeichen wird als Variable "aufgelöst", wenn DelayedExpansion aktiv ist. Aus ..
Echo Microsoft! You 're the best - f*ck the rest!
wird in der Anzeige schlicht
Microsoft
Und selbst "einfache Ausrufungszeichen" am Ende einer Fehlermeldung kann ich mit DelayedExpansion nicht einfach anzeigen:
echo Backup failed!
wird zu
Backup failed
Deshalb möchte ich eigentlich gar nicht, dass M$ bzw. die CMD.exe irgendetwas automatisch zu erkennen versucht..*gg
Bis zum nächsten Batch
Frank / der Biber aus Bremen