FOR循环中的选择 - Windows批处理

Ozr*_*rix 5 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

    :UNINSTALL
        ECHO Odstranuji %%i 
        CALL npm uninstall %%i

    :SKIP
        ECHO Preskakuji %%i
)
Run Code Online (Sandbox Code Playgroud)

Dav*_*ann 8

你的计算是正确的. goto在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
Run Code Online (Sandbox Code Playgroud)
  1. goto 不能for循环中使用.
  2. 括号内设置的变量需要延迟扩展才能检索新值.!而不是%.否则,将使用括号范围之前的变量值.


jim*_*ark 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
    )
)
Run Code Online (Sandbox Code Playgroud)

我在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
Run Code Online (Sandbox Code Playgroud)