我有这个循环,它为外部文件中的每一行重复自己。我想提示用户在每次传递中做出选择,尽管这不起作用。我认为问题在于GOTO命令以某种方式打破了循环。有什么想法吗?
FOR /F %%i IN (%WORKDIR%\grunt-packages.ini) DO (
CHOICE /C AN /M "Odinstalovat plugin"
IF %ERRORLEVEL%==1 GOTO UNINSTALL
IF %ERRORLEVEL%==2 GOTO SKIP
:UNINSTALL
ECHO Odstranuji %%i
CALL npm uninstall %%i
:SKIP
ECHO Preskakuji %%i
)
答案 0 :(得分:8)
你的计算是正确的。 for循环中的goto
将停止循环。解决这个问题的方法是使用call
代替。但是,您的脚本的第一个问题是ERRORLEVEL
变量需要延迟扩展。每当扩展在括号范围内设置的变量时,请使用延迟扩展来获取最新值。
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
FOR /F %%i IN (%WORKDIR%\grunt-packages.ini) DO (
CHOICE /C AN /M "Odinstalovat plugin"
IF !ERRORLEVEL!==1 CALL :UNINSTALL
IF !ERRORLEVEL!==2 CALL :SKIP
)
ENDLOCAL
GOTO :EOF
:UNINSTALL
ECHO Odstranuji %%i
CALL npm uninstall %%i
GOTO :EOF
:SKIP
ECHO Preskakuji %%i
GOTO :EOF
goto
无法在for
循环内使用。!
代替%
。否则,将使用括号范围之前的变量值。答案 1 :(得分:6)
@ Metzger的回答是一个好的开始(我投了票),但我发现它有些问题。最后,我更喜欢将代码内联并避免使用CALLs
。这是我的测试代码,展示了它是如何完成的:
@echo off
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
FOR %%i IN (A B C D) DO (
CHOICE /C AN /M "Uninstall plugin %%i"
IF !ERRORLEVEL!==1 (
ECHO Uninstall %%i
) ELSE IF !ERRORLEVEL!==2 (
ECHO Skip %%i
)
)
我在Windows XP上测试了@ Metzger的答案,发现了以下问题:
GOTO :EOF
(已修复)%%i
未设置ERRORLEVEL
,则可能会调用SKIP 此测试代码修复了问题:
@echo off
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
FOR %%i IN (A B C D) DO (
CHOICE /C AN /M "Uninstall plugin %%i"
SET OERRORLEVEL=!ERRORLEVEL!
IF !ERRORLEVEL!==1 CALL :UNINSTALL %%i
IF !OERRORLEVEL!==2 CALL :SKIP %%i
)
ENDLOCAL
GOTO :EOF
:UNINSTALL
ECHO Uninstall %1
GOTO :EOF
:SKIP
ECHO Skip %1
GOTO :EOF
答案 2 :(得分:1)
此结构避免使用DELAYEDEXPANSION
@ECHO OFF
SETLOCAL
FOR %%i IN (A B C D) DO (
SET destcall=BADCHOICE
choice /c QJ /M "%%i - choose Q or J"
IF ERRORLEVEL 1 SET destcall=CHOSEQ
IF ERRORLEVEL 2 SET destcall=CHOSEJ
CALL CALL :%%destcall%%
)
GOTO :eof
:badchoice
ECHO bad choice
GOTO :eof
:choseq
ECHO You chose Q
GOTO :eof
:chosej
ECHO You chose J
GOTO :eof