arealhobo
arealhobo

Reputation: 467

Batch Script - Skip on errorlevel in a For loop

I am trying to have this script go to the next part if the error level of a ping to a computer does not equal 0, but I cannot get it to work. The output says the syntax is not correct. Thank you.

@echo
setlocal EnableDelayedExpansion

for /f %%a in (main.txt)  do ( 
ping -n 1 %%a > NUL
IF %ERRORLEVEL%==0 (GOTO :COPY) ELSE GOTO :SKIP

:COPY
ROBOCOPY C:\Blah C:\Bloh
ECHO FILE COPIED

:SKIP
 ECHO FILE NOT COPIED
 )

Upvotes: 3

Views: 2521

Answers (2)

aschipfl
aschipfl

Reputation: 34979

goto :Label inside a parenthesised block of code like for loops breaks the block/loop context, so the code at the label is executed as if it were outside of the block/loop. Therefore you need to work around that.


Dennis van Gils points out a way how to do it -- using if/else logic (his method as well as the following slightly modified snippet (applying numeric comparison) both require delayed expansion):

setlocal EnableDelayedExpansion
for "usebackq" /F %%A in ("main.txt") do (
    > nul ping -n 1 %%A
    if !ErrorLevel! EQU 0 (
        robocopy "C:\Blah" "C:\Bloh"
        echo FILE COPIED
    ) else (
        echo FILE NOT COPIED
    )
)
endlocal

Or like this, avoiding the necessity of delayed expansion:

for "usebackq" /F %%A in ("main.txt") do (
    > nul ping -n 1 %%A
    if ErrorLevel 1 (
        echo FILE NOT COPIED
    ) else (
        robocopy "C:\Blah" "C:\Bloh"
        echo FILE COPIED
    )
)

To check the ErrorLevel against (non-)zero, you can also use the && and || operators:

for "usebackq" /F %%A in ("main.txt") do (
    > nul ping -n 1 %%A || (
        echo FILE NOT COPIED
    ) && (
        robocopy "C:\Blah" "C:\Bloh"
        echo FILE COPIED
    )
)

Finally, if you do want to keep the goto :Label structure, you need to use a sub-routine in order to move this part of the code outside of the () block (you also do not need delayed expansion here):

for "usebackq" /F %%A in ("main.txt") do (
    > nul ping -n 1 %%A
    call :SUB "C:\Blah" "C:\Bloh"
)
exit /B

:SUB
if %ErrorLevel% NEQ 0 goto :SKIP
robocopy "%~1" "%~2"
echo FILE COPIED
:SKIP
goto :EOF

Upvotes: 0

Dennis van Gils
Dennis van Gils

Reputation: 3471

You should try this:

@echo
setlocal EnableDelayedExpansion

for /f %%a in (main.txt) do ( 
  ping -n 1 %%a >NUL
  IF "!ERRORLEVEL!"=="0" (
    ROBOCOPY "C:\Blah" "C:\Bloh"
    ECHO FILE COPIED
  ) ELSE (
    ECHO FILE NOT COPIED
  )
)
PAUSE

There are a couple of things wrong with your code. First of all, you enable Delayed Expansion, but don't actually use it, only variables inside ! get expanded delayed. I also put quotes around your filepaths, to protect them against paths with spaces and stuff. Finally, goto and labels don't work inside for loops, so you need to replace them with if else logic

Upvotes: 3

Related Questions