我有一个技巧来做到这一点!
我想出了这种方法,因为在 CLI 上,无法使用此处其他答案中提供的方法,而且它一直困扰着我。
我称之为“直到中断”或“无限”循环:
基本示例
FOR /L %L IN (0,0,1) DO @(
ECHO. Counter always 0, See "%L" = "0" - Waiting a split second&ping -n 1 127.0.0.1>NUL )
这真是一个无限循环!
这对于监视CMD
窗口中的某些内容很有用,并允许您在完成后使用CTRL
+C
来破坏它。
想要柜台吗?
要么使用SET /A
OR 您可以修改FOR /L
循环来进行计数并且仍然是无限的(注意,这两种方法都有 32 位整数溢出)
SET /A
方法:
FOR /L %L IN (0,0,1) DO @(
SET /A "#+=1"&ECHO. L Still equals 0, See "%L = 0"! - Waiting a split second &ping -n 1 127.0.0.1>NUL )
本机FOR /L
计数器:
FOR /L %L IN (-2147483648,1,2147483648) DO @(
ECHO.Current value of L: %L - Waiting a split second &ping -n 1 127.0.0.1>NUL )
计数 4294967295 组并显示 L 的当前值:
FOR /L %L IN (1,1,2147483648) DO @(
(
IF %L EQU 0 SET /A "#+=1">NUL
)&SET /A "#+=0"&ECHO. Sets of 4294967295 - Current value of L: %L - Waiting a split second &ping -n 1 127.0.0.1>NUL )
但是,如果:
- 您有兴趣查看监视器的输出,并担心我会在完成后检查它之前通过 9999 行缓冲区限制。
- 一旦我正在监视的事物完成,您想采取一些额外的行动。
为此,我确定了如何使用几种方法FOR
过早地打破循环,有效地将其变成“ DO WHILE
”或“ DO UNTIL
”循环,否则 CMD 非常缺乏这种循环。
注意:大多数情况下,循环将继续迭代您检查的条件,这通常是一种想要的行为,但在我们的例子中不是。
将“无限循环”变成“ DO WHILE
”/“ DO UNTIL
”循环
更新:由于想在 CMD 脚本(并让它们持久化!)以及 CLI 中使用此代码,并且考虑是否可能有“更正确”的方法来实现这一点,我建议使用新方法!
新方法(可以在 CMD 脚本中使用而无需退出脚本):
FOR /F %%A IN ('
CMD /C "FOR /L %%L IN (0,1,2147483648) DO @( ECHO.%%L & IF /I %%L EQU 10 ( exit /b ) )"
') DO @(
ECHO %%~A
)
在 CLI:
FOR /F %A IN ('
CMD /C "FOR /L %L IN (0,1,2147483648) DO @( ECHO.%L & IF /I %L EQU 10 ( exit /b ) )"
') DO @(
ECHO %~A
)
原始方法(可以在 CLI 上正常工作,但会杀死脚本。)
FOR /L %L IN (0,1,2147483648) DO @(
ECHO.Current value of L: %L - Waiting a split second &ping -n 1 127.0.0.1>NUL&(
IF /I %L EQU 10 (
ECHO.Breaking the Loop! Because We have matched the condition!&DIR >&0
)
)
) 2>NUL
较早的帖子
偶然的机会,我发现了一些过早退出循环的方法,这些方法在尝试做其他给我这个想法的事情时并没有关闭 CMD 提示。
笔记:
虽然ECHO.>&3 >NUL
在某些情况下对我有用,但多年来我断断续续地玩这个,发现它DIR >&0 >NUL
更加一致。
我正在从这里重新编写这个答案以使用该方法,因为我最近发现自己的旧笔记改为使用此方法。
用更好的方法编辑的帖子如下:
DIR >&0 >NUL
>NUL 是可选的,我只是不想让它输出错误。
我更喜欢在可能的情况下匹配 inLine,正如您在我用于监控 VNX 上的 LUN 迁移的命令的净化示例中所见。
for /l %L IN (0,0,1) DO @(
ECHO.& ECHO.===========================================& (
[VNX CMD] | FINDSTR /R /C:"Source LU Name" /C:"State:" /C:"Time " || DIR >&0 >NUL
) & Ping -n 10 1.1.1.1 -w 1000>NUL )
另外,我在给自己的笔记中发现了另一种方法,我刚刚重新测试了它以确认在 CLI 上的工作方式与另一种方法一样好。
显然,当我第一次在这里发帖时,我发布了一个我正在玩的旧版本,而不是两个更好的新版本:
在此方法中,我们使用EXIT /B
退出 For 循环,但我们不想退出 CLI,因此我们将其包装在 CMD 会话中:
FOR /F %A IN ('CMD /C "FOR /L %L IN (0,1,10000000) DO @( ECHO.%L & IF /I %L EQU 10 ( exit /b ) )" ') DO @(ECHO %~A)
因为循环本身发生在 CMD 会话中,我们可以使用 EXIT /B 退出循环的迭代,而不会丢失我们的 CMD 会话,也无需等待循环完成,这与其他方法非常相似。
我什至会说这种方法可能是您想要在 CLI 上打破 for 循环的那种场景的“预期”方法,因为使用 CMD 会话也是使延迟扩展工作的唯一方法循环的 CLI,以及行为和此类行为显然是离开 CMD 会话的预期工作流。
IE:Microsoft 显然有意让 CMD Exit /B For 循环以这种方式运行,而作为我的另一种方法,这样做的“预期”方式依赖于意外创建正确的错误以将您踢出循环而不让循环完成处理,这是我偶然发现的,并且似乎只有在使用相当奇怪的 DIR 命令时才能可靠地工作。
也就是说,我认为使用方法 2 可能是一种更好的做法:
FOR /F %A IN ('CMD /C "FOR /L %L IN (0,1,10000000) DO @( ECHO.%L & IF /I %L EQU 10 ( exit /b ) )" ') DO @(ECHO %~A)
虽然我怀疑方法 1 会稍微快一些:
FOR /L %L IN (0,1,10000000) DO @( ECHO.%L & IF /I %L EQU 10 ( DIR >&) >NUL ) )
在任何一种情况下,两者都应该根据您的目的允许 DO-While 循环。