Pourquoi ce fichier de commandes ne sort-il jamais de la boucle?
For /L %%f In (1,1,1000000) Do @If Not Exist %%f Goto :EOF
Le Goto :EOF
ne devrait-il pas sortir de la boucle?
Je suppose que j'aurais dû demander plus explicitement ... comment puis-je sortir de la boucle?
Vous pouvez simplement utiliser echo on
et vous verrez que goto :eof
ou même exit /b
ne fonctionne pas comme prévu.
Le code à l'intérieur de la boucle n'est plus exécuté, mais la boucle est développée pour tous les nombres jusqu'à la fin.
C'est pourquoi c'est si lent.
La seule façon de sortir d'une boucle FOR/L semble être la variante de exit
comme l'exemple de Wimmel, mais ce n'est ni très rapide ni utile pour accéder aux résultats de la boucle.
Cela montre 10 extensions, mais aucune d'entre elles ne sera exécutée
echo on
for /l %%n in (1,1,10) do (
goto :eof
echo %%n
)
Basé sur la deuxième édition de Tim et cette page vous pouvez le faire:
@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
Cette page suggère un moyen d’utiliser un goto dans une boucle, cela semble fonctionner, mais cela prend du temps dans une grande boucle. Donc, en interne, il termine la boucle avant l'exécution de la goto.
Donc, je réalise que c'est un peu vieux, mais après beaucoup de recherches sur Google, je ne pouvais pas trouver de réponse qui me satisfasse, alors j'ai proposé ma propre solution pour casser une boucle FOR qui arrête immédiatement l'itération, et j'ai pensé partager il.
La boucle doit figurer dans un fichier séparé et exploite un bogue dans la gestion des erreurs CMD pour bloquer immédiatement le traitement par lots du fichier de boucle lors de la redirection du STDOUT de DIR vers STDIN.
MainFile.cmd
ECHO Simple test demonstrating loop breaking.
ECHO.
CMD /C %~dp0\LOOP.cmd
ECHO.
ECHO After LOOP
PAUSE
LOOP.cmd
FOR /L %%A IN (1,1,10) DO (
ECHO %%A
IF %%A EQU 3 DIR >&0 2>NUL )
)
Lorsqu'il est exécuté, cela produit la sortie suivante. Vous remarquerez que l'itération et l'exécution de la boucle s'arrêtent lorsque% A = 3.
:>MainFile.cmd
:>ECHO Simple test demonstrating loop breaking.
Simple test demonstrating loop breaking.
:>ECHO.
:>CMD /C Z:\LOOP.cmd
:>FOR /L %A IN (1 1 10) DO (
ECHO %A
IF %A EQU 3 DIR 1>&0 2>NUL
)
:>(
ECHO 1
IF 1 EQU 3 DIR 1>&0 2>NUL
)
1
:>(
ECHO 2
IF 2 EQU 3 DIR 1>&0 2>NUL
)
2
:>(
ECHO 3
IF 3 EQU 3 DIR 1>&0 2>NUL
)
3
:>ECHO.
:>ECHO After LOOP
After LOOP
:>PAUSE
Press any key to continue . . .
Si vous devez conserver une seule variable de la boucle, indiquez à la boucle ECHO le résultat de la variable et utilisez une boucle FOR/F dans MainFile.cmd pour analyser la sortie du fichier LOOP.cmd.
Exemple (utilisant le même fichier LOOP.cmd que ci-dessus):
MainFile.cmd
@ECHO OFF
ECHO.
ECHO Simple test demonstrating loop breaking.
ECHO.
FOR /F "delims=" %%L IN ('CMD /C %~dp0\LOOP.cmd') DO SET VARIABLE=%%L
ECHO After LOOP
ECHO.
ECHO %VARIABLE%
ECHO.
PAUSE
Sortie:
:>MainFile.cmd
Simple test demonstrating loop breaking.
After LOOP
3
Press any key to continue . . .
Si vous devez conserver plusieurs variables, vous devrez les rediriger vers des fichiers temporaires, comme indiqué ci-dessous.
MainFile.cmd
@ECHO OFF
ECHO.
ECHO Simple test demonstrating loop breaking.
ECHO.
CMD /C %~dp0\LOOP.cmd
ECHO After LOOP
ECHO.
SET /P VARIABLE1=<%TEMP%\1
SET /P VARIABLE2=<%TEMP%\2
ECHO %VARIABLE1%
ECHO %VARIABLE2%
ECHO.
PAUSE
LOOP.cmd
@ECHO OFF
FOR /L %%A IN (1,1,10) DO (
IF %%A EQU 1 ECHO ONE >%TEMP%\1
IF %%A EQU 2 ECHO TWO >%TEMP%\2
IF %%A EQU 3 DIR >&0 2>NUL
)
Sortie:
:>MainFile.cmd
Simple test demonstrating loop breaking.
After LOOP
ONE
TWO
Press any key to continue . . .
J'espère que d'autres trouveront cela utile pour rompre des boucles dont la sortie prendrait trop de temps en raison d'une itération continue.
Comme jeba noté , le reste de la boucle est ignoré mais évalué, ce qui rend la solution FOR
trop lente à cette fin. Une alternative:
set F=1
:nextpart
if not exist "%F%" goto :EOF
echo %F%
set /a F=%F%+1
goto nextpart
Vous devrez peut-être utiliser expansion retardée et call
lors de l’utilisation de cela dans les boucles.
En supposant que l'OP appelle un fichier de commandes avec cmd.exe, pour sortir correctement d'une boucle for, allez simplement à une étiquette;
Change ça:
For /L %%f In (1,1,1000000) Do If Not Exist %%f Goto :EOF
Pour ça:
For /L %%f In (1,1,1000000) Do If Not Exist %%f Goto:fileError
.. do something
.. then exit or do somethign else
:fileError
GOTO:EOF
Mieux encore, ajoutez des rapports d'erreur:
set filename=
For /L %%f In (1,1,1000000) Do(
set filename=%%f
If Not Exist %%f set tempGoto:fileError
)
.. do something
.. then exit or do somethign else
:fileError
echo file does not exist '%filename%'
GOTO:EOF
Je trouve que ce site est utile à propos des astuces et des fonctions de fichier de commandes cmd.exe/DOS moins connues: https://www.dostips.com/