Why does this batch file never break out of the loop?
For /L %%f In (1,1,1000000) Do @If Not Exist %%f Goto :EOF
Shouldn't the Goto :EOF break out of the loop?
Edit:
I guess I should've asked more explicitly... how can I break out of the loop?
Why does this batch file never break out of the loop?
For /L %%f In (1,1,1000000) Do @If Not Exist %%f Goto :EOF
Shouldn't the Goto :EOF break out of the loop?
I guess I should've asked more explicitly... how can I break out of the loop?
you do not need a seperate batch file to exit a loop using exit /b if you are using call instead of goto like
call :loop
echo loop finished
goto :eof
:loop
FOR /L %%I IN (1,1,10) DO (
echo %%I
IF %%I==5 exit /b
)
in this case, the "exit /b" will exit the 'call' and continue from the line after 'call' So the output is this:
1
2
3
4
5
loop finished
My answer
Use nested for loops to provide break points to the for /l loop.
for %%a in (0 1 2 3 4 5 6 7 8 9) do (
for %%b in (0 1 2 3 4 5 6 7 8 9) do (
for /l %%c in (1,1,10) do (
if not exist %%a%%b%%c goto :continue
)
)
)
:continue
Explanation
The code must be tweaked significantly to properly use the nested loops. For example, what is written will have leading zeros.
"Regular" for loops can be immediately broken out of with a simple goto command, where for /l loops cannot. This code's innermost for /l loop cannot be immediately broken, but an overall break point is present after every 10 iterations (as written). The innermost loop doesn't have to be 10 iterations -- you'll just have to account for the math properly if you choose to do 100 or 1000 or 2873 for that matter (if math even matters to the loop).
History I found this question while trying to figure out why a certain script was running slowly. It turns out I used multiple loops with a traditional loop structure:
set cnt=1
:loop
if "%somecriteria%"=="finished" goto :continue
rem do some things here
set /a cnt += 1
goto :loop
:continue
echo the loop ran %cnt% times
This script file had become somewhat long and it was being run from a network drive. This type of loop file was called maybe 20 times and each time it would loop 50-100 times. The script file was taking too long to run. I had the bright idea of attempting to convert it to a for /l loop. The number of needed iterations is unknown, but less than 10000. My first attempt was this:
setlocal enabledelayedexpansion
set cnt=1
for /l %%a in (1,1,10000) do (
if "!somecriteria!"=="finished" goto :continue
rem do some things here
set /a cnt += 1
)
:continue
echo the loop ran %cnt% times
With echo on, I quickly found out that the for /l loop still did ... something ... without actually doing anything. It ran much faster, but still slower than I thought it could/should. Therefore I found this question and ended up with the nested loop idea presented above.
Side note
It turns out that the for /l loop can be sped up quite a bit by simply making sure it doesn't have any output. I was able to do this for a noticeable speed increase:
setlocal enabledelayedexpansion
set cnt=1
@for /l %%a in (1,1,10000) do @(
if "!somecriteria!"=="finished" goto :continue
rem do some things here
set /a cnt += 1
) > nul
:continue
echo the loop ran %cnt% times
It is impossible to get out of a FOR /L before it completes all iterations.
I have debugged the execution of a FOR /L by the cmd.exe process.
Microsoft could document it better and save us all this effort.
Facts:
while (TRUE) and the break only happens when the iteration limit is reached.EXIT /b or a GOTO is encountered, no more commands are executed until the end of the iterations.EXIT is encountered, the cmd.exe process is terminated.Tests:
12 seconds
FOR /L %%G in (1,1,5000000) do (ECHO Only once & GOTO :EOF)
7 seconds
FOR /L %%G in (1,1,5000000) do (ECHO Only once & EXIT /b)
0 seconds, but this terminates the cmd.exe process
FOR /L %%G in (1,1,5000000) do (ECHO Only once & EXIT)