Ответ 4
У меня есть хитрость для этого!
Я придумал этот метод, потому что в то время как в 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
, либо вы можете изменить цикл 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, а также при размышлении о том, существует ли для этого "более правильный" метод, я рекомендую использовать метод New!
Новый метод (может использоваться внутри сценариев 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, когда это возможно, как вы можете видеть в этом очищенном примере команды, которую я использую для мониторинга миграций LUN на нашем VNX.
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 Loop, но мы не хотим выходить из 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 и без ожидания завершения цикла, почти так же, как и в другом методе.
Я бы сказал, что этот метод, вероятно, является "предназначенным" для сценария, в котором вы хотите разорвать цикл for в CLI, поскольку использование сеанса 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, как вам нужно для ваших целей.