0

The requirement is: a file contains multiple line, each of which is a windows cmd. Execute one by one and provide error resolving after each command execution.

My code looks like below:

set RESPOUND=z

for /F "tokens=*" %%A in (%FILE%) do (
    :REPEAT
    call %%A 
    if NOT %ERRORLEVEL% == 0 (
        :INVALID    
        set /p RESPOUND="Execution on %%A Failed, (R)etry, (S)kip, (A)bort:"
        if %RESPOUND%=="r" GOTO REPEAT
        if %RESPOUND%=="s" GOTO SKIP
        if %RESPOUND%=="a" GOTO ABORT
        echo %RESPOUND%
        GOTO INVALID 
    )
    :SKIP
    echo test
)

:ABORT

This it turns out that unlike other coding languages, the variables are instantly be filled with preset value, so here ERRORLEVEL is filled with 0 when the entire for is read, making the condition always lose effect; Similarly, RESPOUND is already set to z, so that even I alter the previous condition and break into, the inner part does not work because all %RESPOUND% has already be replaced by z before then.

Additionally, if the echo test line is removed, the batch will report unexpected ) in syntax error, which also confusing me.

So how to change the code to make it work?

Compo
  • 36,585
  • 5
  • 27
  • 39
a4194304
  • 366
  • 2
  • 13
  • 2
    You cannot use labels within a parenthesized `for` loop. _I indented your code to better show you had done that to other readers too._ – Compo Apr 24 '23 at 08:07
  • 3
    You also should be aware of the [delayed expansion trap](https://stackoverflow.com/a/30284028/2128947) and please consider `choice` which is designed for this task. Use the search facility for [batch-file] choice eg [Gerhard's example](https://stackoverflow.com/a/58370914/2128947) or see the documentation - `choice /?` from the prompt. – Magoo Apr 24 '23 at 10:30

1 Answers1

0

After reading comments and documents, I worked out a solution. Maybe not best practice but works.

for /F "tokens=*" %%A in (%FILES%) do (
    SET ITEM=%%A
    call :EXECUTE !ITEM!
)

pause
GOTO :eof

:EXECUTE
:REPEAT
call %EXECUTOR_BAT% %1

if NOT !ERRORLEVEL! == 0 (
    echo Execution on %1 Failed 
    choice /c ria /n /m "(R)etry, (I)gnore, (A)bort:"
    set CHOOSE=!ERRORLEVEL!

    if !CHOOSE!==0 exit
    if !CHOOSE!==1 GOTO REPEAT
    :: !CHOOSE!==2 CONTINUE THE PROCESS
    if !CHOOSE!==3 exit
)

exit /B

where delayed expansion is used and using call to prevent :labels to break the loop.

a4194304
  • 366
  • 2
  • 13