evinben
Goto Top

GOTO EOF in FOR-Schleife beendet leider die ganze Batch-Datei. Aufruf mit Call dagegen nicht. Erklärung hierfür?

Hallo,

das Ziel hier ist zwei Datensätze nacheinander abzuarbeiten ({bootmgr} und {current}) und insgesamt nur zwei Ergebnisse anzuzeigen (also pro Datensatz nur ein Ergebnis).
GOTO :EOF in der untergeordneten FOR-Schleife beendet nach dem ersten gefundenen Ergebnis leider nicht dieselbe und kehr zurück zu der übergeordneten, sondern im Anschluss den ganzen Batch-Prozess.
So eine Konstruktion führt nicht zu dem gewünschten Ergebnis:

back-to-topNicht funktionierender Code

:Eintrags-IDs/GUIDs anhand des Typs (der Kurzschreibweise) ermitteln.
setlocal EnableDelayedExpansion
for %%d in (
	{bootmgr}
	{current}
	) do (
		set Type=%%d
		for /f "tokens=2 delims={}" %%e in ('bcdedit /enum !Type! /v ^|findstr /r "[{-}]"') do (  
			set GUID=%%e
			echo !GUID!
			goto :eof
			)
		)
setlocal DisableDelayedExpansion

echo ERFOLG und PAUSE
:timeout /t 3 >nul
pause >nul
Wir kommen so nicht zu der ECHO-Ausgabe "ERFOLG und PAUSE".

Mit CALL-Aufruf-Methode funktioniert der Prozess wie erwartet, jedoch interessiert mich nun brennend andere Lösungen zu erfahren und am besten solche, die nicht zu arg sehr wie Grashüpfer hin und her hüpfen (z. B. solche innerhalb der FOR-Schleife, ähnlich wie in dem 1. Beispiel schon mal angedeutet ist).

back-to-topFunktionierender Code

:Eintrags-IDs/GUIDs anhand des Typs (der Kurzschreibweise) ermitteln.
setlocal EnableDelayedExpansion
for %%d in (
	{bootmgr}
	{current}
	) do set Type=%%d & call :M5

echo ERFOLG und PAUSE
:timeout /t 3 >nul
pause >nul


:M5
for /f "tokens=2 delims={}" %%e in ('bcdedit /enum %Type% /v ^|findstr /r "[{-}]"') do (  
	set GUID=%%e
	echo !GUID!
	goto :eof
	)
setlocal DisableDelayedExpansion

Natürlich bin ich für alle Lösungen offen.
Verbesserungsvorschläge sind immer willkommen.

Gruß
evinben

Content-Key: 196651

Url: https://administrator.de/contentid/196651

Printed on: April 19, 2024 at 20:04 o'clock

Member: Hitman4021
Hitman4021 Jan 08, 2013 at 22:49:33 (UTC)
Goto Top
Hallo,

Batch ist zwar nicht so meins aber, goto springt zum betreffenden Punkt und call sollte nur die Funktion aufrufen. Solange ich mich nicht Irre!

Gruß
Member: evinben
evinben Jan 08, 2013 at 22:59:37 (UTC)
Goto Top
Hallo Hitman4021,

GOTO hat hier eine besondere Funktion und dieser Befehl benutz hier eine besondere Sprungmarke, nämlich :EOF (End Of File). Wir wissen ja, dass in FOR /F-Schleife generell eine untergeordnete CMD aufgerufen wird. D. h. hier soll der untergeordnete Prozess beendet werden, sobald sich etwas erledigt hat, also GOTO :END OF FILE in dem untergeordneten CMD-Prozess. Bitte eventuell um Korrektur.

Gruß
evinben
Member: bastla
bastla Jan 08, 2013 updated at 23:31:57 (UTC)
Goto Top
Hallo evinben!

Eine (ungetestete) Alternative könnte etwa so aussehen:
:Eintrags-IDs/GUIDs anhand des Typs (der Kurzschreibweise) ermitteln.
setlocal EnableDelayedExpansion
for %%d in (
    {bootmgr}
    {current}
) do (
    set "Type=%%d"  
    set "GUID="  
    for /f "tokens=2 delims={}" %%e in ('bcdedit /enum !Type! /v ^|findstr /r "[{-}]"') do (  
        if not defined GUID (
            set "GUID=%%e"  
            echo !GUID!
        )
    )
)
setlocal DisableDelayedExpansion

echo ERFOLG und PAUSE
:timeout /t 3 >nul
pause >nul
Etwas schlanker:
:Eintrags-IDs/GUIDs anhand des Typs (der Kurzschreibweise) ermitteln.
for %%d in ({bootmgr},{current}) do (
    set "GUID="  
    for /f "tokens=2 delims={}" %%e in ('bcdedit /enum %%d /v ^|findstr /r "[{-}]"') do (  
        if not defined GUID (
            set "GUID=%%e"  
            echo %%e
        )
    )
)

echo ERFOLG und PAUSE
:timeout /t 3 >nul
pause >nul
Grüße
bastla
Mitglied: 106543
106543 Jan 09, 2013 at 07:32:30 (UTC)
Goto Top
Hi,

wenn ich mich nicht all zu sehr irre, bewirkt dein "goto", dass die Batch an die gegebene Stelle springt während "call" alles was nach der betreffenden Sprungmarke steht ausführt und danach zum Ursprungsort zurückkehrt.

Grüße
Exze
Member: evinben
evinben Jan 09, 2013 at 10:05:38 (UTC)
Goto Top
Hallo Bastla!

dankbar dir habe ich nun den Fehler erkannt, was mich am meistens freut und vor allem beruhigt.
Nämlich muss ich ab nun verstärkt darauf achten nicht wieder zu vergessen, dass bei Verwendung von setlocal EnableDelayedExpansio die Variable explizit gelöscht werden muss (hier im Falle set "GUID="). Ansonsten wird diese in die nächste Runde mitgeschleppt und daher hat bei meinen Versuche if not defined GUID nicht weiter geholfen gehabt (da sie so doch bis zu der allerletzten Runde definiert bleibt und daher werden im Gegensatz zu meinem Wunsch alle Ergebnisse ausgegeben).
Obwohl ich solche Fälle (bei Verwendung von setlocal EnableDelayedExpansio) schon mal erlebt habe, bei denen ich die Fehler dann verspätet gefunden habe (set var=), bin ich nach mehrmaligem Experimentieren diesmal einfach nicht drauf gekommen. Etwas Rutine fehlt noch …

Danke, dass es euch hier gibt!

Und Bastla du darfst dir gerne wieder ein Eis wünschen.

Gruß
evinben