5

外部ファイルのすべての行に対して繰り返されるこのループがあります。これは機能しませんが、すべてのパスでユーザーに選択を促したいと思います。問題は、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
)
4

3 に答える 3

8

あなたの計算は正しいです。 gotoforループ内でループを停止します。これを回避する方法は、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
  1. goto forループ内では使用できません。
  2. 括弧内に設定された変数は、新しい値を取得するために拡張を遅らせる必要があります。!の代わりに%。それ以外の場合は、括弧スコープの前の変数の値が使用されます。
于 2013-03-12T12:51:10.490 に答える
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ん(すでに修正されています)
  • 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
于 2013-03-12T13:35:29.933 に答える
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
于 2013-03-12T14:20:00.130 に答える