退出批处理文件中的FOR循环?

Meh*_*dad 24 for-loop batch-file break

为什么这个批处理文件永远不会脱离循环?

For /L %%f In (1,1,1000000) Do @If Not Exist %%f Goto :EOF
Run Code Online (Sandbox Code Playgroud)

不应该Goto :EOF突破循环?

编辑:

我想我应该更明确地问... 我怎么能摆脱循环?

wim*_*ica 8

基于Tim的第二次编辑此页面,您可以这样做:

@echo off
if "%1"=="loop" (
  for /l %%f in (1,1,1000000) do (
    echo %%f
    if exist %%f exit
  )
  goto :eof
)
cmd /v:on /q /d /c "%0 loop"
echo done
Run Code Online (Sandbox Code Playgroud)

这个页面提出了一种在循环中使用goto的方法,它看起来确实有效,但在大循环中需要一些时间.所以在内部它在执行goto之前完成循环.

  • 除非您确实要关闭当前会话,否则不要在批处理文件中使用`exit`.如果从命令提示符运行批处理,这不是很好. (5认同)
  • 啊,没有注意到那里的'cmd`调用.不过,感觉很脏. (2认同)

jeb*_*jeb 6

您可以简单地使用echo on,您将看到goto :eof甚至exit /b不能按预期工作.

循环内部的代码不再执行,但循环会针对所有数字进行扩展.
这就是它如此缓慢的原因.

退出FOR/L循环的唯一方法似乎是exitWimmel示例的变体,但这对于从循环中访问任何结果来说并不是非常快速也没有用.

这显示了10个扩展,但没有一个会被执行

echo on
for /l %%n in (1,1,10) do (
  goto :eof
  echo %%n
)
Run Code Online (Sandbox Code Playgroud)


ave*_*rry 6

我的回答
使用嵌套for循环为循环提供断点for /l

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
Run Code Online (Sandbox Code Playgroud)

说明 必须对代码进行大量调整才能正确使用嵌套循环。例如,写入的内容会有前导零。可以使用简单的命令立即打破
“常规”循环,而循环则不能。此代码的最内层循环无法立即中断,但每 10 次迭代后就会出现一个整体断点(如所写)。最里面的循环不必是 10 次迭代——如果您选择执行 100 或 1000 或 2873 次(如果数学对循环很重要),您只需正确考虑数学即可。 forgotofor /lfor /l

历史 我在试图找出为什么某个脚本运行缓慢时发现了这个问题。事实证明,我使用了具有传统循环结构的多个循环:

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
Run Code Online (Sandbox Code Playgroud)

该脚本文件变得有些长,并且是从网络驱动器运行的。这种类型的循环文件可能被调用 20 次,每次会循环 50-100 次。脚本文件运行时间太长。我有一个好主意,尝试将其转换为for /l循环。所需的迭代次数未知,但小于 10000。我的第一次尝试是这样的:

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
Run Code Online (Sandbox Code Playgroud)

随着echoon,我很快发现循环for /l仍然做了......一些事情......但实际上没有做任何事情。它运行得快得多,但仍然比我想象的要慢。因此,我发现了这个问题,并最终得出了上面提出的嵌套循环的想法。

旁注事实证明 ,只需确保循环没有任何输出,就for /l可以大大加快循环速度。我能够这样做以显着提高速度:

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
Run Code Online (Sandbox Code Playgroud)


Nic*_*tok 5

如果您使用 call 而不是 goto ,则不需要单独的批处理文件来使用 exit /b 退出循环

call :loop

echo loop finished

goto :eof

:loop
FOR /L %%I IN (1,1,10) DO (
    echo %%I
    IF %%I==5 exit /b
)
Run Code Online (Sandbox Code Playgroud)

在这种情况下,“exit /b”将退出“call”并从“call”之后的行继续,因此输出如下:

1
2
3
4
5
loop finished
Run Code Online (Sandbox Code Playgroud)


Rap*_*oso 5

FOR /L在完成所有迭代之前不可能退出 a 。

FOR /L我已经调试了进程的执行cmd.exe

Microsoft 可以更好地记录它并节省我们所有的精力。

事实:

  1. 该循环很简单while (TRUE),并且break仅在达到迭代限制时才会发生。
  2. 当遇到 anEXIT /b或 aGOTO时,不再执行任何命令,直到迭代结束。
  3. EXIT当遇到an时,cmd.exe进程终止。

测试:

12秒

FOR /L %%G in (1,1,5000000) do (ECHO Only once & GOTO :EOF)
Run Code Online (Sandbox Code Playgroud)

7秒

FOR /L %%G in (1,1,5000000) do (ECHO Only once & EXIT /b)
Run Code Online (Sandbox Code Playgroud)

0秒,但这会终止cmd.exe进程

FOR /L %%G in (1,1,5000000) do (ECHO Only once & EXIT)
Run Code Online (Sandbox Code Playgroud)


Tim*_*Tim -1

对此进行了一些研究,看来您正在从 1 循环到 2147483647,增量为 1。

(1, 1, 2147483647):第一个数字是起始数字,下一个数字是步骤,最后一个数字是结束数字。

编辑添加

看起来无论任何测试条件如何,循环都会运行到完成。我测试过

FOR /L %%F IN (1, 1, 5) DO SET %%F=6
Run Code Online (Sandbox Code Playgroud)

而且跑得很快。

第二次编辑

由于这是批处理文件中的唯一行,您可以尝试 EXIT 命令:

FOR /L %%F IN (1, 1, 2147483647) DO @IF NOT EXIST %%F EXIT
Run Code Online (Sandbox Code Playgroud)

但是,这也会关闭 Windowscmd提示窗口。