Batch file 循环中的选项-Windows批处理

Batch file 循环中的选项-Windows批处理,batch-file,Batch File,我有一个循环,它在外部文件中的每一行都会重复自己。我想在每次通过时提示用户进行选择,尽管这不起作用。我认为问题在于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 :

我有一个循环,它在外部文件中的每一行都会重复自己。我想在每次通过时提示用户进行选择,尽管这不起作用。我认为问题在于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
)

你的估计是对的<代码>转到for循环内将停止循环。解决这个问题的方法是使用
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
    循环中使用
  • 括号内设置的变量需要延迟展开才能检索新值<代码>而不是
    %
    。否则,将使用括号范围之前的变量值

  • @梅茨格的回答是一个好的开始(我投了赞成票),但我发现了一些问题。最后,我更喜欢将代码内联,避免调用
    。下面是我的测试代码,展示了它是如何完成的:

    @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
      (已修复)
    • 在Windows XP上,在子例程
      %中,未设置%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
    

    此结构避免使用延迟扩展

    @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
    

    +1这些都是值得注意的要点<代码>:)
    特别是关于卸载中可能设置的错误级别。我曾考虑将passing
    %%I
    作为一个参数,但我认为它不是必需的(按原样在7和8上工作)。